Linq query FromSql where passing string value - c#

Have a SQL table example column Id-Pk-int, Name-varchar(250), ...
Using EF Core
when I execute
var data= (from c in _db.Table.FromSql($"select * from Emp where id=1")
select c).FirstOrDefault();
returns successfully
but when I execute using where clause name (string)
var data = (from c in _db.Table.FromSql($"select * from Emp where Name=Mike")
select c).FirstOrDefault();
I get an exception, System.Data.SqlClient.SqlException: 'Invalid column name 'Mike'.'
I tested if I changed the data in the database column: Name to 123 (number) it works but fails when value is string

I think the problem is occured because of you forgot to use ' symbol. Because exception says there is no column named Mike. And column name should be "Name" as i see from the code.
Check if Name column is VARCHAR. If the column is VARCHAR you need use ' symbols. If not you can use like WHERE ID=1
Use that;
var data = (from c in _db.Table.FromSql($"select * from Emp where Name='Mike'")
select c).FirstOrDefault();
Edit 2: I see that you said Id-int, Name-varchar. Can you use the code i wrote? Thanks.

You should use proper parameterization, do not concatenate or interpolate data into a query, or you will leave yourself open to injection attacks and syntax errors.
var data = (from c in _db.Table.FromSql("select * from Emp where Name = #name",
new SqlParameter("#name", SqlDbType.VarChar, 50){Value = "Mike"})
select c).FirstOrDefault();
var data = (from c in _db.Table.FromSql("select * from Emp where Id = #id",
new SqlParameter("#id", SqlDbType.Int){Value = 1})
select c).FirstOrDefault();
In newer versions of EF Core, use FromSqlRaw in the same way.

Related

How to add column in SELECT statement dynamically in tSQL based on condition?

I am creating a tSql with parameters and based on some condition I want to add column in SELECT statement and I am not sure how to do it.
My Logic:
var keywordClause = keyword.IsNotEmpty()
? "[Name] like '%" + keyword + "%'"
: "1 = 1";
// keywordClause = "[Name] like '%Test%'"
var orderBy = sortParameters.ToOrderBy();
// orderBy = "Name ASC"
var parameters = new List<SqlParameter>
{
new SqlParameter("#Keyword", keywordClause),
new SqlParameter("#OrderBy", orderBy)
};
var sql = string.Format(#"SELECT Id,
Name,
CreateDateTime Created
FROM CallCenter WITH (NOLOCK)
WHERE(IsDeleted = 0)
AND #Keyword
ORDER BY #OrderBy");
return _PageList(ctx => ctx.CallCenterSummaries.SqlQuery(sql, parameters.ToArray())
.AsQueryable()
.Select(d => d.TrimSpaces()), page, pageSize);
Based on my logic, I am expecting this query:
SELECT Id,
Name,
CreateDateTime Created
FROM CallCenter WITH (NOLOCK)
WHERE(IsDeleted = 0)
AND [Name] like '%Test%'
ORDER BY Name ASC;
Here I am getting "An expression of non-boolean type specified in a context where a condition is expected, near 'ORDER'." exception and I believe it is taking Name as a string. How can I get desired results?
You can't have SqlParameter as an entire clause - it needs to be right hand side of the clause. For your scenario - the below should work.
var parameters = new List<SqlParameter>
{
new SqlParameter("#Keyword", keyword.IsNotEmpty() ? keyword : "%")
};
var sql = string.Format($#"SELECT Id,
Name,
CreateDateTime Created
FROM CallCenter WITH (NOLOCK)
WHERE(IsDeleted = 0)
AND [Name] like #Keyword
ORDER BY {orderBy}");
EDIT:
I've edited my code sample to use order by as a value in the interpolated string rather than as a SqlParameter, however, this does open you up to a Sql injection if the value of the orderBy is influenced by user's inputs.
Alternatively, I would recommend not using ORDER BY clause at all in your query and sorting results in memory before passing them back for display.

field not found according to npgsql, but it exists according to pgadmin

I have this line of code as my query in C#:
cmd.CommandText = "SELECT *
FROM product
LEFT JOIN category ON product.category_id = category.id
WHERE product.id = #productId";
The product table has a column called name which I need.
This is the line I use in my application to retrieve it.
product.ProductName = reader.GetString(reader.GetOrdinal("\"product\".\"name\""));
The error I'm getting is
System.IndexOutOfRangeException: Field not found
on that line.
reader.GetOrdinal("name");
Firstly the resultset does not have a field named "product"."name", but rather one named "name". Consider that if you were to try to select from that resultset within PostgreSQL it would be the same case:
SELECT "product"."name" FROM
(SELECT *
FROM product
LEFT JOIN category ON product.category_id = category.id
WHERE product.id = #productId) subquery
Doesn't work, but:
SELECT "name" FROM
(SELECT *
FROM product
LEFT JOIN category ON product.category_id = category.id
WHERE product.id = #productId) subquery
Does.
Secondly, don't use the PostgreSQL escaping on the name of the field.

Problemin getting correct query result in asp.net using join

I am learning ASP.net and I have come to the point that I want to insert, update, delete records in a database.
Currently I am trying to read out values out of 2 tables using "join" but when I display the results in a grid the Foreign Key values are still like : 2, 1, 2,... Instead I want them to be to coresponding words.
This is the current query I am using:
from p in dc.Personeels join a in dc.Afdelingens on p.fk_personeel_afdeling equals a.pk_afdeling_id select p
Does anyone know what I am doing wrong?
Try this query
var query = from p in dc.Personeels
join a in dc.Afdelingens on p.fk_personeel_afdeling equals a.pk_afdeling_id
select new
{
id = p.id, // your id from table dc.Personeels
name = a.name // Name from table dc.Afdelingens
} into x
select x;

Issue Related to where clause in SQL Server

I have a table name Students having (studentId, StudentName,Address,PhoneNo)
i have provided a filter for user to select only StudentId from Combobox to get the details of Students... and generate Report.
I have written following Query to get student Detail :
(select * from Students where StudentId = stdId)
Here stdId is a Parameter that i pass from code
It works fine if i select single studentId.... But in user selection Comobobox i have also provided "ALL" if user Select All from combobox i want to display details of all student
So what should I pass in stdId if user selects All ?
I used inline Query in C# (not using SQL Stored Procedure)
You can do it like this .
SELECT * from Students s
WHERE s.studentId = ISNULL(#StudentId,s.studentId)
When "All" is selected in combo box pass null in your #studentid parameter. If you can not pass null in parameter then pass -1 or anything which can not be contain in you combox option and do it like this:(if -1= All)
SELECT * from Students s
WHERE s.studentId = #StudentId or #StudentId=-1
You can also try the answer given by Curt.
If user selects all, pass NULL to #StudentId and change your query to:
select *
from Students
where (StudentId=#StudentId OR #StudentId IS NULL)
In your stored procedure header, change the definition of #StudentId so that it can be passed as NULL.
ALTER PROCEDURE dbo.WhateverYourProcedureIsCalled( #StudentId int = null )
Then change your WHERE clause as follows
...
SELECT * from Students
WHERE #StudentId IS NULL OR StudentId = #StudentId
From your code, if ALL is passed, you can omit the part where you set the value of the #StudentId parameter. SQL Server will use the default if not passed.
If the where clause is included in the query you also need to supply a valid parameter value and it is therefore not possible to get all students when the where clause is included.
You need to differentiate your query based on the value selected in the combobox. You can do something like the following.
int studentId = 0;
//Where selectedValue comes from your combobox
Int32.TryParse(selectedValue, out studentId);
var query = "select * from Students";
if (studentId > 0)
{
query = query + " where StudentId = #StudentId";
//Remember to add studentId as parameter value
}

Getting distinct rows in LINQ

I need to get the distinct row values from a table using LINQ. The query i used is
var results = (from statename in dsobject.dbo_statetable select statename).Distinct();
It is giving all the rows of the table named "dbo_statetable" but i need only the distinct statename. What should be the query to achieve this?
Its sql equivalent is select distinct statename from dbo_statetable
You need to specify the property:
var results = (from x in dsobject.dbo_statetable select x.Statename).Distinct();
// ^^^^^^^^^^
The variable after from does not specify the column. It is like a table alias in SQL. Your LINQ statement is roughly equivalent to this SQL:
SELECT DISTINCT * FROM dbo_statetable AS statename
dsobject.dbo_statetable.Select(s => s.statename).Distinct()

Categories