Executing Raw SQL Queries using Entity Framework

原文 Executing Raw SQL Queries using Entity Framework

While working with Entity Framework developers mostly use LINQ to Entities to query database. However, at times you may need to execute raw queries against the database. A common scenario is when you wish to generate an SQL query dynamically. Luckily, EF allows you to execute raw queries easily. This article explains how that can be done.

In the examples discussed below it is assumed that you have entity data model created for the Customer table of the Northwind database. The following figure shows this model:

Let's see how SELECT and UPDATE queries can be executed against the Northwind database using the EF context generated by the designer.

Executing SELECT queries that return entities

This technique is useful when you wish to execute a query or stored procedure that returns entities. For example, you may wish to retrieve customers that reside in the USA. To accomplish this task you can write the following code:

DbSqlQuery<Customer> data = db.Customers.SqlQuery("select * from customers
                            where country=@p0", "USA");
foreach(var cust in data)
{
  //do something with cust
}

As you can see the above code calls SqlQuery() method on the Customers DbSet. The SqlQuery() method executes a specified SELECT query and returns the results of that entity type (Customer in this case). The SqlQuery() method accepts two parameters - the SELECT query to be executed and zero or more parameters. It is always recommended to use parameters instead of string concatenation to avoid security issues. In the above example the SELECT query has one parameter with name @p0. The parameter names must be of the form p0, p1, p2 and so on. Index must start from 0. The second parameter of SqlQuery() accepts parameter values in the same sequence of the parameter names. There is an alternate technique of supplying the parameters that is discussed later in this article.

The return value of SqlQuery() is DbSqlQuery and can be used to access / iterate through the data returned by the query.

Executing SELECT queries that return custom types

Not just entities, you can also fetch custom types from the database. For example, you may wish to execute a JOIN statement and retrieve the results. Or you may need to fetch data from a table that is not included in your model at all. Consider the following code:

DbRawSqlQuery<CustomerInfo> data = db.Database.SqlQuery<CustomerInfo>
                                   ("select customerid,companyname,contactname,country
                                   from customers where country=@p0", "USA");
foreach (var custinfo in data2)
{
  //do something custinfo
}

Note a few changes here. In this case, SqlQuery() method is called on the Database object rather than DbSet. This is because the query doesn't return entities. This time SqlQuery() expects the type of the resultant objects in the result. In this case CustomerInfo class is used and is shown below:

public class CustomerInfo
{
  public string CustomerID { get; set; }
  public string CompanyName { get; set; }
  public string ContactName { get; set; }
  public string Country { get; set; }
}

The return type this time is DbRawSqlQuery based on CustomerInfo type. Once the query is executed the results are loaded in CustomerInfo objects. You can access / iterate through the results as in the previous example.

Executing action queries

To execute action queries (INSERT, UPDATE, DELETE) you use ExecuteSqlCommand() method of the Database object. Just like SqlQuery() method, ExecuteSqlCommand() method also takes the same two parameters. The following code fragment shows how ExecuteSqlCommand() can be used:

string sql = "INSERT INTO CUSTOMERS(CUSTOMERID,COMPANYNAME,CONTACTNAME,COUNTRY)
              VALUES(@P0,@P1,@P2,@P3)";
List<object> parameterList = new List<object>();
parameterList.Add("AAAAA");
parameterList.Add("Company 1");
parameterList.Add("Contact 1");
parameterList.Add("USA");
object[] parameters1 = parameterList.ToArray();
int result = db.Database.ExecuteSqlCommand(sql, parameters);

This example uses slightly different approach to execute an INSERT query. The INSERT query is stored in a string variable. Notice how the parameter names are specified as @P0, @P1, @P2 and @P3. Instead of passing these parameters in the ExecuteSqlCommand() method itself, a List of objects is created and parameter values are added to it. This List is then converted to an array of objects. Finally,  ExecuteSqlCommand() is called by passing the query and the parameters.

The return value of ExecuteSqlCommand() is an integer that reveals the number of records affected by  the query.

Alternate way of passing parameters

In all the above examples you used index based parameter naming convention. Although that worked as expected, the parameter names such as @p1 are far from being readable. Fortunately, you can also specify named parameters in the queries. However, if you wish to use named parameters you must supply the parameters in the form of SqlParameter objects. The following example shows how this can be done.

string sql = "INSERT INTO CUSTOMERS(CUSTOMERID,COMPANYNAME,CONTACTNAME,COUNTRY)
              VALUES(@custid,@company,@contact,@country)";
List<SqlParameter> parameterList = new List<SqlParameter>();
parameterList.Add(new SqlParameter("@custid","AAAAA"));
parameterList.Add(new SqlParameter("@company", "Company 2"));
parameterList.Add(new SqlParameter("@contact", "Contact 2"));
parameterList.Add(new SqlParameter("@country", "USA"));
SqlParameter[] parameters = parameterList.ToArray();
int result = db.Database.ExecuteSqlCommand(sql, parameters);

As you can see the parameters are now specified as @custid, @company, @contact and @country. The List of SqlParameter is then created and parameters are added to it. Note that parameters are now defined as SqlParameter objects that map a parameter name to its value.

That's it for this article! Keep coding!!

   

   

Bipin Joshi is a software consultant, a trainer, an author and a yogi having 20+ years of experience in software development. He conducts professional courses in ASP.NET, jQuery, AngularJS, HTML5 and Design Patterns in Thane. He is a published author and has authored or co-authored books for Apress and Wrox press. Having embraced Yoga way of life he also enjoys writing about the classical yoga system. To know more about him click here. To know more about his training programs go here.

时间: 2024-11-08 17:52:01

Executing Raw SQL Queries using Entity Framework的相关文章

看看Entity Framework 4生成的复杂的分页SQL语句

之前发现Entity Framework 4生成的COUNT查询语句问题,今天又发现它生成的分页SQL语句问题,而LINQ to SQL却不存在这个问题. >>> 来看一看,瞧一瞧! 上代码: 看生成的SQL语句: 1. Entity Framework生成的SQL: 一个TOP,三个FROM. 2. LINQ to SQL生成的SQL: 无TOP,两个FROM. 两者的差距一目了然. >>> 再来看一个: 将上面代码中Where的查询条件改为常量,即Where(cod

Microsoft SQL Server Compact 4.0&amp;&amp;ADO.NET Entity Framework 4.1&amp;&amp;MVC3

原文:Microsoft SQL Server Compact 4.0&&ADO.NET Entity Framework 4.1&&MVC3 最近重新查看微软MvcMusicStore-v3.0的源代码,发现忽略了很多重要的东西,特别是数据访问那一部分. 首先Microsoft SQL Server Compact 4.0 详细的介绍和下载地址 链接:http://www.microsoft.com/zh-cn/download/details.aspx?id=17876

看看Entity Framework 4生成的复杂的分页SQL语“.NET研究”句

之前发现Ent上海网站建设ity Framework 4生成的COUNT查询语句问题,今天又发现它生成的分页SQL语句问题,而LINQ to SQL却不存在这个问题. >>> 来看一看,瞧一瞧! 上代码: 看生成的SQL语句: 1. Entity Framework生成的SQL: 一个TOP,三个FROM. 上海闵行企业网站设计与制作 2. LINQ to SQL生成的SQL: 无TOP,两个FROM. 两者的差距一目了然. >>> 再来看一个: 将上面代码中Where

一起谈.NET技术,看看Entity Framework 4生成的复杂的分页SQL语句

之前发现Entity Framework 4生成的COUNT查询语句问题,今天又发现它生成的分页SQL语句问题,而LINQ to SQL却不存在这个问题. >>> 来看一看,瞧一瞧! 上代码: 看生成的SQL语句: 1. Entity Framework生成的SQL: 一个TOP,三个FROM. 2. LINQ to SQL生成的SQL: 无TOP,两个FROM. 两者的差距一目了然. >>> 再来看一个: 将上面代码中Where的查询条件改为常量,即Where(cod

Using the Repository Pattern with ASP.NET MVC and Entity Framework

原文:http://www.codeguru.com/csharp/.net/net_asp/mvc/using-the-repository-pattern-with-asp.net-mvc-and-entity-framework.htm Introduction Data driven web applications need to have a neat strategy for data access. One of the important aspects of this str

下一代ADO.NET---ADO.NET Entity Framework

ado ADO.NET Entity Framework的目标 从纷繁芜杂的关系数据模型中抽象出概念模型.这样开发人员可以只需着眼概念模型,而不必要去关心纷繁芜杂的关系数据模型,从而提高开发效率. 那么如何能够做到这一点?答案就是:Language-Integrated Query 和 ADO.NET Entity Framework,也就是下一代的ADO.NET. ADO.NET Entity Framework包括 1. 实体数据模型(Entity Data Model),开发人员通过EDM

Entity Framework 6:专家版本

随着 Entity Framework 最新主版本 EF6 的推出,Microsoft 对象关系映射 (ORM) 工具达到了新的专业高度,与久负盛名的 .NET ORM 工具相比已不再是门 外汉. EF 已经完全成熟,正在超越以前广泛使用的工具. Entity Framework 已经度过了青涩期,它最初只是供数据库开发者使用的工 具,后来在 .NET 社区的敏捷开发者中间引起轰动. 它学会了如何摆脱应用程序 开发模式,转向了普通旧 CLR 对象 (POCO) 模型,支持以测试和域为中心的软件

Entity Framework中的全角半角符号问题

SQL Server的SQL查询不区分大小写,而LINQ查询区分大小写,所以在写LINQ代码时需要注意的是 --如果这段LINQ代码将会被Entity Framework解析为SQL语句(LINQ to Entities),则不 用考虑大小写问题:如果这段LINQ代码在内存中执行,就要考虑大小写的问题. 比如下面的LINQ to Entities(不用考虑大小写): //代码自来CNBlogsTagService _unitOfWork.Set<Tag>().Where(x => tag

ADO.NET Entity Framework(1)介绍

目录 1 概念 1 2 ADO.NET Entity Framework 2 2.1 架构 2 2.2 说明 2 2.3 EntityConnection 4 2.4 EntityCommand 5 2.5 通过EntityDataReader 方式的数据访问 6 2.6 通过ObjectContext返回ObjectQuery<T> 方式的数据访问 9 概念 LINQ to Entities 一种 LINQ 技术,使开发人员可以使用 LINQ 表达式和 LINQ 标准查询运算符,针对实体数据