EntLib.com 专业电子商务平台

基于Microsoft .Net Framework / ASP.Net / C# / AJAX 平台构建的标准电子商务系统
随笔 - 99, 评论 - 74, 引用 - 0

Entity Data Model (EDM) 深入分析, Part 2

Entity Data Model (EDM) 深入分析, Part 2
 
 
实体 SQL (Entity SQL),它是一种新的 SQL 语言,其中加入了之前的 SQL 语言并不支持的基于概念的查询功能。ESQL 扩展现有 SQL 语言的方式与 EDM 扩展数据库中所使用的关系模型的方式十分类似。此外,ESQL 未绑定到任何特定于后台数据库的语法,因此可一次性编写查询(和/或应用程序),无论针对的是哪个后台数据库都无影响。
 
Entity SQL 是基于文本的、面向集合的、延后绑定的查询语言,也受到了T-SQL的影响。可以使用Entity SQL 创建对EDM的查询,Entity SQL 既可以通过Object Services components来执行,也可以通过Entity Client components 来执行。Entity SQL 设计的非常灵活,因此也变得有些复杂。本篇文章侧重于不同的查询技术,仅仅使用简单的查询,不包含复杂的条件、关联和聚合公式。

本系列文章上一篇:
Entity Data Model (EDM) 深入分析, Part 1
 
1. 使用ObjectQuery<T> 查询返回实体类型(Entity Type)集合
下面演示如何执行Entity SQL 查询,返回实体类型的实例集合。
1) 首先创建Northwind ObjectContext 实例。
2) Entity SQL语句本身是字符串表达式,在大多数情况下,由SELECT-FROM 查询语句组成。在SELECT语句中使用VALUE关键字来表示返回的实体是一条数据行。
3) 使用Object Services components 执行查询。调用ObjectContext 的工厂方法CreateQuery<T>(),创建一个ObjectQuery 对象,该对象表示对存储数据源的查询,查询表达式为Entity SQL 语句。
4) Entity Framework实体框架采用延迟装载(Deferred loading)。因此只有在显式需要数据时,才真正执行SQL语句。在这种情况下,在ForEach第一次迭代时,才执行查询语句。
 
NorthwindEntities context = new NorthwindEntities();
 
var sql = "SELECT VALUE emp FROM NorthwindEntities.Employees AS emp";
var query = context.CreateQuery<Employee>(sql);
 
foreach (var emp in query)
 Console.WriteLine("{0} {1} {2} {3}", emp.EmployeeID, emp.FirstName, emp.LastName, emp.Country);
 
除了使用工厂方法CreateQuery<T>外,也可以直接创建ObjectQuery对象实例,并传入Object Context 参数,示例代码如下:
NorthwindEntities context = new NorthwindEntities();
 
var sql = "NorthwindEntities.Employees";
ObjectQuery<Employee> query = new ObjectQuery<Employee>(sql, context);
 
foreach (var emp in query)
 Console.WriteLine("{0} {1} {2} {3}", emp.EmployeeID, emp.FirstName, emp.LastName, emp.Country);
 
下面增加一个WHERE条件:
var sql = "SELECT VALUE emp FROM NorthwindEntities.Employees AS emp " +
          "WHERE emp.Country = 'USA'";
var query = context.CreateQuery<Employee>(sql);
 
2. 带参数的ObjectQuery<T>查询
参数变量是在Entity SQL外定义的,在查询语句中需要以@符合作为前缀定义变量名。参数定义为ObjectParameter 对象,然后增加到ObjectQuery 实例中。
 
下面增加一个Country 变量:
var sql = "SELECT VALUE emp FROM NorthwindEntities.Employees AS emp " +
          "WHERE emp.Country = @country";
var query = context.CreateQuery<Employee>(sql);
query.Parameters.Add(new ObjectParameter("country", "USA"));
 
同样以ObjectQuery 示例对象实现这一功能:
var sql = "SELECT VALUE emp FROM NorthwindEntities.Employees AS emp " +
          "WHERE emp.Country = @country";
ObjectQuery<Employee> query = new ObjectQuery<Employee>(sql, context);
query.Parameters.Add(new ObjectParameter("country", "USA"));
 
ObjectParameter对象也可以直接传入CreateQuery<T>方法:
var sql = "SELECT VALUE emp FROM NorthwindEntities.Employees AS emp " +
          "WHERE emp.Country = @country";
var query = context.CreateQuery<Employee>(sql, new ObjectParameter("country", "USA"));
 
第三种方法的是使用Where 扩展方法,使用关键字it 指向当前的查询语句:
var sql = "SELECT VALUE emp FROM NorthwindEntities.Employees AS emp";
var query = context.CreateQuery<Employee>(sql)
 .Where("it.Country = @country", new ObjectParameter("country", "USA"));
 
3. ObjectQuery<T> 查询返回基本类型(Primitive Type)
除了返回实体类型外,也可以返回基本类型集合,因此需要确保SELECT语句仅仅返回1个值,同时也需要在CreateQuery方法中指定需要返回的基本类型。
var sql = "SELECT VALUE emp.EmployeeID FROM NorthwindEntities.Employees AS emp " +
           "WHERE emp.Country = @country";
var query = context.CreateQuery<int>(sql, new ObjectParameter("Country", "USA"));
 
foreach (var id in query)
 Console.WriteLine("{0}", id.ToString());
 
另一示例脚本:
var sql = "SELECT VALUE emp.Country FROM NorthwindEntities.Employees AS emp " +
          "WHERE emp.EmployeeID = @id";
var query = context.CreateQuery<string>(sql, new ObjectParameter("id", 1));
 
Console.WriteLine(query.First());
 
除了使用 Entity SQL外,你也能使用查询构造(Query Builder)方法实现相同的效果。Entity SQL 提供了SelectValue 方法,可以提过隐式的行构造器,仅仅返回指定的列。
string country = context.Employees.SelectValue<string>("it.Country", new ObjectParameter("id", 1)).First();
 
Console.WriteLine(country);
 
4. ObjectQuery<T> 查询返回匿名类型
也有可能需要调整数据,并使用ObjectQuery<T>查询返回匿名类型。在CreateQuery 方法中,改变SELECT语句并使用DbDataRecord 类,DbDataReader类在.NET 1.0引入,它提供了对任何枚举类型的数据绑定支持。
var sql = "SELECT emp.LastName, emp.FirstName " +
           "FROM NorthwindEntities.Employees AS emp ";
var query = context.CreateQuery<DbDataRecord>(sql);
 
foreach (var emp in query)
 Console.WriteLine("{0} {1}", emp[0], emp[1]);
 
另一示例代码:
var sql = "SELECT emp.LastName AS FamilyName, emp.FirstName " +
           "FROM NorthwindEntities.Employees AS emp ";
var query = context.CreateQuery<DbDataRecord>(sql);
 
foreach (var emp in query)
 Console.WriteLine("{0} {1}", emp["FamilyName"], emp["FirstName"]);

后续内容关于EntityClient,待续 ---


推荐Entity Framework 相关文章:
1. Entity Framework – Update Model From Database, Part 1
2. Entity Framework – Update Model From Database, Part 2
3. Entity Framework 架构简介
4. 比较LINQ to SQL Diagram 和Entity Data Model
 
英文链接:
1. ADO.NET Entity Framework & LINQ to Entities,

 

 打印 | 评论 (6) | posted on 2008年10月21日 23:14 | 目录 [ ASP.NET 3.5 ]

评 论

# re: Entity Data Model (EDM) 深入分析, Part 2

学习中,看到这个教程觉得不错,呵呵
2008/12/4 16:05 | yuanhongguo

# re: Entity Data Model (EDM) 深入分析, Part 2

真是服了你,这么好的工具就被你这样用了。
2009/1/29 5:26 | Victor

# re: Entity Data Model (EDM) 深入分析, Part 2

Victor,

欢迎提出你的高见. Thanks.
2009/1/29 12:05 | entlib

# re: Entity Data Model (EDM) 深入分析, Part 2

不会吧。那用ESQL还不如用Linq to Entities,强类型的验证还是保险点
2009/4/21 16:35 | DavidLv

# re: Entity Data Model (EDM) 深入分析, Part 2

感觉有些奇怪。
EF和L2S的引入就是提供一种对象模型来进行数据库的操作,而直接操作的是model,那么在操作中更应该是一种OO方式,而不是像直接操作数据库那样拼接sql字符串。
在使用ef和l2s时要尽量避免拼接sql字符串。
2009/5/27 16:42 | fgg

# re: Entity Data Model (EDM) 深入分析, Part 2

LZ,我和你一样的做法,为什么提示NorthwindEntities里面没有Employees
2009/11/4 16:57 | wei

发表评论

标题  
姓名  
Email
主页
评论内容   
Please add 8 and 2 and type the answer here: