Reputation: 904
I am currently converting functions in the DAL of an old app to a new app using Entity Framework/LINQ in its DAL.
There are some instances where I would like to directly pass a string of sql to the database. Is this possible when using LINQ? Here is what I tried atfer research but ExecuteQuery is not available.
using (var context = new DbContext())
{
var sql = @"SELECT DISTINCT * FROM Customer where CustomerId = {0}";
sql = string.Format(sql, customerId);
var query = DbContext.ExecuteQuery<Customer>(sql);
return query.ToList();
}
Doing this seems pretty straight forward but ExecuteQuery is not available to me.
Here is my next attempt at it which seems much better: (please tell me if there is a better way)
StringBuilder sql = new StringBuilder();
sql.AppendLine("SELECT * FROM CUSTOMERS ");
sql.AppendLine("WHERE @CustomerId = null OR CustomerId = @CustomerId ");
sql.AppendLine("AND @CustomerName = null OR CustomerName = @CustomerName ");
var customerList = context.Customers.SqlQuery(sql.ToString(),
new SqlParameter("@CustomerId", customerId),
new SqlParameter("@CustomerName", customerName)).ToList();
Upvotes: 0
Views: 3363
Reputation: 20585
Although for your current condition you can use LINQ.
var customer = context.Customers.Where(c => c.CustomerId = id).Distinct();
This is how you do it Entity Framework Raw SQL Queries
using (var context = new DbContext())
{
context.Database.SqlCommand(
"UPDATE dbo.Blogs SET Name = 'Another Name' WHERE BlogId = 1");
}
using (var context = new DbContext())
{
var customers = context.Customers.SqlQuery("SELECT * FROM dbo.Customers").ToList();
}
using (var context = new DbContext())
{
var customers = context.Blogs.SqlQuery("dbo.GE_Customers").ToList();
}
using (var context = new DbContext())
{
var customerNames = context.Database.SqlQuery<string>(
"SELECT Name FROM dbo.Customers").ToList();
}
Update to answer
You do not need to pass SqlParameter, simply pass the default objects
I think the code below should work fine.
var customerList = context.Customers.SqlQuery(sql.ToString(), customerId, customerName).ToList();
if your real query is
sql.AppendLine("SELECT * FROM CUSTOMERS ");
sql.AppendLine("WHERE @CustomerId = null OR CustomerId = @CustomerId ");
sql.AppendLine("AND @CustomerName = null OR CustomerName = @CustomerName ");
I would suggest you to do it this way
var customers = context.Costomers; // this does not populates the result yet
if (!String.IsNullOrEmpty(customerId))
{
customers = customers.Where(c => c.CustomerId = customerId); // this does not populates the result yet
}
if (!String.IsNullOrEmpty(customerName))
{
customers = customers.Where(c => c.CustomerName = customerName); // this does not populates the result yet
}
// finally execute the query
var custList = customers.ToList();
Upvotes: 2
Reputation: 152594
You can use SqlQuery
, but it would be better to pass the parameter instead of using Format
:
var sql = @"SELECT DISTINCT * FROM Customer where CustomerId = {0}";
var query = DbContext.SqlSuery<Customer>(sql, customerId);
That way, the parameters are SQL encoded so as not to allow for SQL Injection.
Upvotes: 1
Reputation: 2989
If there is not limitation or requirement don't use this kind of queries they are vulnerable to sql inject attacks.
You can do nearly every sentence with Entity Framework using linq, like the one you wrote
DbContext.Customer.Where(c => c.CustomerId = id).Distinct();
It's more readable, and more secure.
Upvotes: 2