分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow
也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!
Entity Framework 学习初级篇1--EF基本概况...2
Entity Framework 学习初级篇2--ObjectContext、ObjectQuery、ObjectStateEntry、ObjectStateManager类的介绍...7
Entity Framework 学习初级篇3-- LINQ TOEntities.10
Entity Framework 学习初级篇4--EntitySQL.17
Entity Framework 学习初级篇5--ObjectQuery查询及方法...23
Entity Framework 学习初级篇6--EntityClient.31
Entity Framework 学习初级篇7--基本操作:增加、更新、删除、事务...37
Entity Framework 学习中级篇1—EF支持复杂类型的实现...41
Entity Framework 学习中级篇2—存储过程(上).47
Entity Framework 学习中级篇3—存储过程(中).54
Entity Framework 学习中级篇4—存储过程(下).61
Entity Framework 学习中级篇5—使EF支持Oracle9i67
Entity Framework 学习高级篇1—改善EF代码的方法(上)...75
Entity Framework 学习高级篇2—改善EF代码的方法(下)...81
Entity Framework学习初级篇1--EF基本概况
最近在学习研究微软的EF,通过这时间的学习研究,感觉这个EF目前来说还不是很完善,半成品。不过,据说在.Net4.0中,微软将推荐使用此框架,并会有所改善。而且,现在基本上所有数据库均提供了对EF的支持。因此,为以后做技术准备可以学习研究以下。但是,我个人觉得就目前来说,在实际项目慎用此框架。
下面简单的介绍以下这个EF。
在.Net Framework SP1微软包含一个实体框架(Entity Framework),此框架可以理解成微软的一个ORM产品。用于支持开发人员通过对概念性应用程序模型编程(而不是直接对关系存储架构编程)来创建数据访问应用程序。目标是降低面向数据的应用程序所需的代码量并减轻维护工作。Entity Framework 应用程序有以下优点:
· 应用程序可以通过更加以应用程序为中心的概念性模型(包括具有继承性、复杂成员和关系的类型)来工作。
· 应用程序不再对特定的数据引擎或存储架构具有硬编码依赖性。
· 可以在不更改应用程序代码的情况下更改概念性模型与特定于存储的架构之间的映射。
· 开发人员可以使用可映射到各种存储架构(可能在不同的数据库管理系统中实现)的一致的应用程序对象模型。
· 多个概念性模型可以映射到同一个存储架构。
· 语言集成查询支持可为查询提供针对概念性模型的编译时语法验证。
实体框架Entity Framework 是 ADO.NET 中的一组支持开发面向数据的软件应用程序的技术。在EF中的实体数据模型(EDM)由以下三种模型和具有相应文件扩展名的映射文件进行定义。
· 概念架构定义语言文件 (.csdl) -- 定义概念模型。
· 存储架构定义语言文件 (.ssdl) -- 定义存储模型(又称逻辑模型)。
· 映射规范语言文件 (.msl) -- 定义存储模型与概念模型之间的映射。
实体框架 使用这些基于 XML 的模型和映射文件将对概念模型中的实体和关系的创建、读取、更新和删除操作转换为数据源中的等效操作。EDM 甚至支持将概念模型中的实体映射到数据源中的存储过程。它提供以下方式用于查询EDM 并返回对象:
· LINQ to Entities-- 提供语言集成查询 (LINQ) 支持用于查询在概念模型中定义的实体类型。
· Entity SQL -- 与存储无关的 SQL 方言,直接使用概念模型中的实体并支持诸如继承和关系等 EDM 功能。
· 查询生成器方法 --可以使用 LINQ 风格的查询方法构造 Entity SQL 查询。
下图演示用于访问数据的实体框架体系结构:
下面,来学习EF的基本使用方法。软件环境::
· Visual Studio 2008 +SP1
· SQL Server2005/2008
首先,建立一个名为“EFProject”的解决方案,然后添加一个名为“EFModel”的类库项目。如下图所示。
接着,在EFModel项目中,添加“ADO.NETEntity Data Model”项目,如下图所示:
名称取为“NorthWindEF.edmx”,然后点击“添加”。然后,在后面的步骤中,数据库选择“NorthWind”后,在选择影射对象是,把表、试图、存储过程全部都选上,其他的均保存默认的即可。最终生成的结果如下图所示。
好了,数据模型生成完毕。
最后,谈谈我认为的一些缺点:
· Edmx包含了所有对象的csdl,ssdl,msl文件,过于庞大,如果要手动修改这个文件,一不小心,眼睛看花了,就改错了。(和数据集一样的毛病)。
· 目前EF支持表、试图、存储过程,其他的对象不支持,而且对使用存储过程有很多限制(目前有EFExtension提供了更多对象的支持)。
· 除了MSSQL Server可直接提供这种可视化的设计界面外,其他的数据库目前还没有提供可视化设计界面(但可以自己来实现,后面介绍)。
· 性能问题。(网上看到有说比ADO.Net慢,又有人说比ADO.net快的,具体情况我还没测试过, 但我觉得像这个些类型的框架,性能肯定是比上原生态的ADO.net慢)
好了,接下来,学习以下简单的各种操作。
Entity Framework 学习初级篇2--ObjectContext、ObjectQuery、ObjectStateEntry、ObjectStateManager类的介绍
本节,简单的介绍EF中的ObjectContext、ObjectQuery、ObjectStateEntry、ObjectStateManager这个几个比较重要的类,它们都位于System.Data.Entity.dll下的System.Data.Objects命名空间下。在后续的章节中,我们经常会用到它们的某些方法,以便完成我们的某些操作或目的。本节,简单的说明一下以后我们可能会用到的各个类的方法,以方便我们后续的学习。
ObjectContext封装 .NET Framework 和数据库之间的连接。此类用作“创建”、“读取”、“更新”和“删除”操作的网关。
ObjectContext 类为主类,用于与作为对象(这些对象为 EDM 中定义的实体类型的实例)的数据进行交互。
ObjectContext 类的实例封装以下内容:
l 到数据库的连接,以 EntityConnection 对象的形式封装。
l 描述该模型的元数据,以 MetadataWorkspace 对象的形式封装。
l 用于管理缓存中持久保存的对象的 ObjectStateManager对象。
ObjectContext类的成员方法以说明如下所示:
l AcceptAllChanges()
接受所有对该实体对象的更改
l AddObject(string,object)
将实体对象添加到制定的实体容器中
l ApplyPropertyChanges(string,object)
将以指派的实体对象属性的更改应用到容器中对应的原对象。
l Attach(System.Data.Objects.DataClasses.IEntityWithKeyentity)
将带主键的实体对象附加到默认的容器中
l Attach(string,object)
将实体对象附加到指定的实体容器中
l CreateEntityKey(string,object)
给指定的实体对象创建实体主键或如果已存在实体主键,则直接返回该实体的主键
l CreateQuery<T>(string,paramsObjectParameter[])
从给定的查询字符串创建ObjectQuery对象。
l DeleteObject(object)
删除指定的实体对象
l Detach(object)
移除指定的实体对象
l ExecuteFunction<TElement>(string,paramsObjectParameter[])
对默认容器执行给定的函数。
l GetObjectByKey(System.Data.EntityKeykey)
通过主键KEY从 ObjectStateManager中检索对象(如果存在);否则从存储区中检索。
l Refresh(System.Data.Objects.RefreshMode refreshMode,object entity)
按指定持久更新模式,使用指定实体的存储区数据更新ObjectStateManager。。
l Refresh(System.Data.Objects.RefreshModerefreshMode, System.Collections.IEnumerable collection)
按指定持久处理模式,使用指定实体集的存储区数据更新ObjectStateManager。
l SaveChanges(bool)
将所有更新持久保存到存储区中。参数是客户端事务支持所需的参数。参数为true则在更新后自动将更改应用到ObjectStateManager中的实体。如果为false,则在更新后还需要调用AcceptAllChanges()以便更新ObjectStateManager中的实体。
l SaveChanges()
将所有更新持久保存到存储区中
l TryGetObjectByKey(System.Data.EntityKey,outobject)
尝试从指定实体主键返回该实体
以上各个方法的具体用法,将在后面介绍。
接着,再看看有用的类ObjectQuery。
ObjectQuery有个有用的方法ToTraceString(),这个方法用于追踪所执行的SQL语句,通过此方法我们可以获取所执行的SQL语句,以便我们查看、分析具体执行的SQL语句。(类似Nhibernate配置文件中的showsql节)
再了解一下ObjectStateEntry。
ObjectStateEntry维护实体实例或关系实例的状态(已添加、已删除、已分离、已修改或未更改)、键值和原始值。还管理已修改属性的列表。其包含一下方法:
l AcceptChanges
接受当前值作为原始值,并将实体标记为 Unchanged()。
l Delete
将实体标记为 Deleted()。如果实体处于 Added()()() 状态,它将为 Detached()。
l GetModifiedProperties
返回标记为 Modified()的属性名称。
l SetModified
将状态设置为 Modified()。
l SetModifiedProperty
将指定的属性标记为 Modified()。
接着,再看看ObjectStateManager。
ObjectStateManager用于维护对象映射、对象状态/标识管理以及实体实例或关系实例的持久性。
获取给定EntityState的ObjectStateEntry集合。
获取给定的 EntityKey 对应的 ObjectStateEntry
现在,几个重要的类简单介绍完毕。后面,我们将具体学习它们的使用。
Entity Framework 学习初级篇3-- LINQ TO Entities
LINQ 技术(即 LINQ to Entities)使开发人员能够通过使用 LINQ 表达式和 LINQ 标准查询运算符,直接从开发环境中针对 实体框架对象上下文创建灵活的强类型查询。LINQ to Entities 查询使用对象服务基础结构。ObjectContext 类是作为 CLR 对象与 实体数据模型 进行交互的主要类。开发人员通过 ObjectContext 构造泛型 ObjectQuery 实例。ObjectQuery 泛型类表示一个查询,此查询返回一个由类型化实体组成的实例或集合。返回的实体对象可供更新并位于对象上下文中。以下是创建和执行 LINQ to Entities 查询的过程:
1. 从 ObjectContext 构造 ObjectQuery 实例。
2. 通过使用 ObjectQuery 实例在 C# 或 Visual Basic 中编写 LINQ to Entities 查询。
3. 将 LINQ 标准查询运算符和表达式将转换为命令目录树。
4. 对数据源执行命令目录树表示形式的查询。执行过程中在数据源上引发的任何异常都将直接向上传递到客户端。
5. 将查询结果返回到客户端。
一、Linq To Entities简单查询
下面将介绍简单的Linq To Entities查询,相关的查询语法可以使用基于表达式或基于方法的语法。本节使用的TestDriver.Net配合Nunit2.4进行测试。
1, 投影
代码如下:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Data.Objects;
usingNUnit.Framework;
namespaceNorthWindModel
{
[TestFixture]
public classTestEFModel
{
[Test]
public void Select()
{
using(var edm =new NorthwindEntities())
{
//基于表达式的查询语法
ObjectQuery<Customers> customers = edm.Customers;
IQueryable<Customers> cust1 =fromc in customers
select c;
Assert.Greater(cust1.Count(),0);
//使用ObjectQuery类的ToTraceString()方法显示查询SQL语句
Console.WriteLine(customers.ToTraceString());
}
}
}
}
输出:
SELECT
[Extent1].[CustomerID] AS[CustomerID],
[Extent1].[CompanyName] AS[CompanyName],
[Extent1].[ContactName] AS[ContactName],
[Extent1].[ContactTitle] AS[ContactTitle],
[Extent1].[Address] AS [Address],
[Extent1].[City] AS [City],
[Extent1].[Region] AS [Region],
[Extent1].[PostalCode] AS[PostalCode],
[Extent1].[Country] AS [Country],
[Extent1].[Phone] AS [Phone],
[Extent1].[Fax] AS [Fax]
FROM [dbo].[Customers] AS [Extent1]
1 passed, 0 failed, 0 skipped, took 11.00 seconds (NUnit2.4).
在上面的输出内容中,可以看到使用了ToTraceString()方法来输出具体的SQL语句。同时Nunit也输出相关的测试情况,请注意查询所花费的时间,以便我们进行查询速度的分析比较。
2, 条件限制
using(var edm =new NorthwindEntities())
{
//基于表达式的查询语法
ObjectQuery<Customers> customers = edm.Customers;
IQueryable<Customers> cust1 =from c in customers
where c.CustomerID =="ALFKI"
select c;
Assert.AreEqual(cust1.Count(), 1);
foreach (varcin cust1)
Console.WriteLine("CustomerID={0}", c.CustomerID);
//基于方法的查询语法
var cust2 = edm.Customers.Where(c =>c.CustomerID =="ALFKI");
Assert.AreEqual(cust2.Count(), 1);
foreach (varcin cust2)
Console.WriteLine("CustomerID={0}", c.CustomerID);
}
3, 排序和分页
在使用Skip和Take方法实现分页时,必须先对数据进行排序,否则将会抛异常。
using(var edm =new NorthwindEntities())
{
//基于表达式的查询语法
ObjectQuery<Customers> customers = edm.Customers;
IQueryable<Customers> cust10 = (fromcin customers
orderby c.CustomerID
select c).Skip(0).Take(10);
Assert.AreEqual(cust10.Count(),10);
foreach(var cincust10)
Console.WriteLine("CustomerID={0}", c.CustomerID);
//基于方法的查询语法
var cust =edm.Customers.OrderBy(c => c.CustomerID).Skip(0).Take(10);
Assert.AreEqual(cust.Count(),10);
foreach (var cin cust)
Console.WriteLine("CustomerID={0}", c.CustomerID);
}
4, 聚合
可使用的聚合运算符有Average、Count、Max、Min 和 Sum。
using (varedm =new NorthwindEntities())
{
varmaxuprice = edm.Products.Max(p => p.UnitPrice);
Console.WriteLine(maxuprice.Value);
}
5, 连接
可以的连接有Join 和 GroupJoin 方法。GroupJoin组联接等效于左外部联接,它返回第一个(左侧)数据源的每个元素(即使其他数据源中没有关联元素)。
using(var edm =new NorthwindEntities())
{
var query = from d in edm.Order_Details
joinorder in edm.Orders
ond.OrderID equals order.OrderID
selectnew
{
OrderId =order.OrderID,
ProductId = d.ProductID,
UnitPrice = d.UnitPrice
};
foreach(var qinquery)
Console.WriteLine("{0},{1},{2}",q.OrderId,q.ProductId,q.UnitPrice);
}
其他一些方法等就不多说了,和Linq to SQL基本上是一样的。
二、LINQ to Entities 查询注意事项
l 排序信息丢失
如果在排序操作之后执行了任何其他操作,则不能保证这些附加操作中会保留排序结果。这些操作包括 Select 和 Where 等。另外,采用表达式作为输入参数的First 和FirstOrDefault方法不保留顺序。
如下代码:并不能达到反序排序的效果
using (varedm =new NorthwindEntities())
{
IQueryable<Customers>cc = edm.Customers.OrderByDescending(c => c.CustomerID).Where(c =>c.Region !=null).Select(c => c);
foreach (var cin cc)
Console.WriteLine(c.CustomerID);
}
l 不支持无符号整数
由于 实体框架不支持无符号整数,因此不支持在 LINQ to Entities 查询中指定无符号整数类型。如果指定无符号整数,则在查询表达式转换过程中会引发NotSupportedException异常,并显示无法创建类型为“结束类型”的常量值。此上下文仅支持基元类型(“例如 Int32、String 和 Guid”)。
如下将会报异常的代码:
using(var edm =new NorthwindEntities())
{
uint id = UInt32.Parse("123");
IQueryable<string>produt =from p inedm.Products
where p.UnitPrice == id
select p.ProductName;
foreach (string namein produt)
Console.WriteLine(name);
}
上面的代码中,由于id是uint而不是Int32,String,Guid的标量类型,所以在执行到where p.UnitPrice ==id这个地方时,会报异常。
l 不支持引用非标量闭包
不支持在查询中引用非标量闭包(如实体)。在执行这类查询时,会引发 NotSupportedException 异常,并显示消息“无法创建类型为“结束类型”的常量值。此上下文中仅支持基元类型(‘如 Int32、String 和 Guid’)
如下将会报异常的代码:
using (var edm =new NorthwindEntities())
{
Customers customer = edm.Customers.FirstOrDefault();
IQueryable<string>cc =from c inedm.Customers
where c == customer
select c.ContactName;
foreach (string namein cc)
Console.WriteLine(name);
}
上面的代码中,由于customer是引用类型而不是Int32,String,Guid的标量类型,所以在执行到where c==customer这个地方时,会报异常。
好,本节介绍完毕。后面将继续学习EF.
Entity Framework学习初级篇4--Entity SQL
Entity SQL 是 ADO.NET 实体框架 提供的 SQL 类语言,用于支持 实体数据模型 (EDM)。Entity SQL 可用于对象查询和使用 EntityClient 提供程序执行的查询。
l 关键字
Value关键字
ESQL 提供了 SELECT VALUE 子句以跳过隐式行构造。SELECT VALUE 子句中只能指定一项。在使用这样的子句时,将不会对 SELECT 子句中的项构造行包装器,并且可生成所要形状的集合,例如:SELECTVALUE it FROM NorthwindEntities.Customers as it
it关键字
it 出现在 ESQL 中, 查询对象的别名默认值"it" 改成其他字符串,例如:
"SELECT VALUE it FROM NorthwindEntities.Customersas it "。
l 注释:
Entity SQL 查询可以包含注释。注释行以两个短划线 (--) 开头。
"SELECT VALUE it FROMNorthwindEntities.Customers as it --this a comment "
l Select查询
例如:
SELECT VALUE it FROMNorthwindEntities.Customers as it
l 参数
参数是在esql之外定义的变量,每个参数都有名称和类型,参数名称在查询表达式中定义,并以@符号作为前缀。例如:
Select VALUE c fromNorthwindEntities.Customers as c where c.CustomerID=@customerID
l 聚合
Enity SQL不支持 * ,所以esql不支持count(*),而是使用count(0),例如:
Select count(0) fromNorthwindEntities.Customers
l 分页SKIP/LIMIT
可以通过在 ORDER BY 子句中使用 SKIP 和 LIMIT 子子句执行物理分页。若要以确定的方式执行物理分页,应使用 SKIP 和 LIMIT。如果您只是希望以非确定的方式限制结果中的行数,则应使用 TOP。TOP 和 SKIP/LIMIT 是互斥的
使用SKIP/LIMIT分页,esql代码如下:
Select value c fromNorthwindEntities.Customers as c order by c.CustomerID skip 0 limit 10
l TOP
SELECT 子句可以在可选的 ALL/DISTINCT 修饰符之后具有可选的 TOP 子子句。TOP 子子句指定查询结果中将只返回第一组行。esql代码如下:
Select top(10) c.CustomerID fromNorthwindEntities.Customers as c order by c.CustomerID
l NULL处理
Null 文本与 Entity SQL 类型系统中的任何类型都兼容,可以使用cast进行类型转换,例如:
select cast(c.region as string) fromNorthwindEntities.Customers as c order by c.CustomerID limit 10
其中, Nvarchar等可以成string,数字类型可以转成int32,其他的类型转换类似。如果无法完成转换,则将报异常。还有可以处理的方法有treat。
l 标识符
Entity SQL 提供两种标识符:简单标识符和带引号的标识符
简单标识符:Entity SQL 中的简单标识符是字母数字和下划线字符的序列。标识符的第一个字符必须是字母字符(a-z 或 A-Z)。
带引号的标识符:带引号的标识符是括在方括号 ([]) 中的任何字符序列。带中文的部分,请使用方括号包括起来,否则会报如下异常信息:“简单标识符“中文”只能包含基本拉丁字符。若要使用UNICODE 字符,请使用转义标识符”
正确的代码如下:
Select c.CustomerID as [中文字符] from NorthwindEntities.Customers as c order by c.CustomerIDskip 0 limit 10
l ROW
Esql可使用row来构建匿名的结构类型的纪录。例如:
SELECT VALUE row(p.ProductID asProductID,p.ProductName as ProductName) FROM NorthwindEntities.Products as porder by p.ProductID LIMIT 10
l Key
提取引用或实体表达式的键。如下esql语句,直接返回Customer表的主键:
string esql = "SELECT value key(c)FROM NorthwindEntities.Customers as c order by c.CustomerID LIMIT 10"
l CreateRef/ref/deref
CreateRef创建对实体集中的实体的引用。
ref返回对实体实例的引用,之后就可以当作实体来访问其属性,esql语句如下:
SELECT ref(c).CustomerID FROMNorthwindEntities.Customers as c order by c.CustomerID LIMIT 10
deref运算符取消引用一个引用值,并生成该取消引用的结果。
l CASE语句:
string esql = "using SqlServer;select case whenlen(trim(c.CustomerID))==0 then true else false end from NorthwindEntities.Customers as c orderby c.CustomerID limit 10";
l 运算符
Esql支持的运算符有:加+、减-、乘*、除/、取模%、-负号。Esql语句如下:
select 100/2 as OP fromNorthwindEntities.Customers as c order by c.CustomerID limit 10
l 比较运算符
Esql支持的比较运算符有:=,>,>=,IS [NOT]NULL,<,[NOT] BETWEEN,!=,<>,[NOT] LIKE。Esql语句如下:
select value p fromNorthwindEntities.Products as p where p.UnitPrice > 20 order by p.ProductIDlimit 10
l 逻辑运算符
Esql支持的逻辑运算符有:and(&&),not(!),or(||)。Esql语句如下:
select value p fromNorthwindEntities.Products as p where p.UnitPrice > 20 and p.UnitPrice<100order by p.ProductID limit 10
或
select value p fromNorthwindEntities.Products as p where p.UnitPrice > 20 &&p.UnitPrice<100 order by p.ProductID limit 10
l 字符串连接运算符。
加号 (+) 是 Entity SQL 中可将字符串串联起来的唯一运算符。Esql语句如下:
select c.CustomerID + c.ContactName fromNorthwindEntities.Customers as c orderby c.CustomerID limit 10
l 嵌套查询
在 Entity SQL 中,嵌套查询必须括在括号中,将不保留嵌套查询的顺序
select c1.CustomerID from( select valuec from NorthwindEntities.Customers as c order by c.CustomerID limit 10) as c1
l 日期时间函数
Esql提供的日期时间函数有:CurrentDateTime()获取当前服务器的日期时间,还有month,day,year,second,Minute ,Hour等。例如:
select CurrentDateTime() from NorthwindEntities.Customers as c order by c.CustomerID limit 10
l 字符串函数
Esql提供的字符串函数有:Concat,IndexOf,Left,Length,Ltrim,Replace,Reverse,Rtrim,SubString,Trim,ToLower,ToUpper.例如:
select Reverse(p.ProductName) asProductName from NorthwindEntities.Products as p order by p.ProductID limit 10
l GUID
Esql提供newguid()函数,产生一个新的Guid。例如:
select newguid() from NorthwindEntities.Customers as c order by c.CustomerID limit 10
l 数学函数:
Abs,Ceiling,Floor,Round
l 统计函数:
Avg,BigCount,Count,Max,Min,StDev,Sum
l 位计算函数
如果提供 Null 输入,则这些函数返回 Null。这些函数的返回类型与参数类型相同。如果函数采用多个参数,则这些参数必须具有相同的类型。若要对不同类型执行位运算,则需要显式强制转换为相同类型.
BitWiseAnd,BitWiseNot,BitWiseOr,BitWiseXor
l 命名空间
Entity SQL 引入命名空间以避免全局标识符(如类型名称、实体集、函数等)出现名称冲突。Entity SQL 中的命名空间支持与 .NET Framework 中的命名空间支持类似。
Entity SQL 提供两种形式的 USING 子句:限定命名空间(其中,提供较短的别名以表示命名空间)和非限定命名空间,如下例所示:
USING System.Data;
USING tsql =System.Data;
例如:
string esql = "using System; select cast(p.UnitPrice asInt32) from NorthwindEntities.Productsas p order by p.ProductID limit 10";
string esql = "using System;using SqlServer; select(cast(p.UnitPrice as Int32)),SqlServer.ltrim(p.ProductName) as nameLen fromNorthwindEntities.Products as p order byp.ProductID limit 10 ";
最后,简单说一下Esql与T-Sql的某些差异:
l Entity SQL中的所有列引用都必须用表别名限定.
l Esql不支持Any,all限定运算符以及*运算
l Entity SQL当前未提供对 DML 语句(insert、update、delete)的支持。
l Entity SQL 的当前版本未提供对 DDL的支持。
Entity Framework学习初级篇5--ObjectQuery查询及方法
ObjectQuery 类支持对 实体数据模型 (EDM) 执行 LINQ to Entities 和 Entity SQL 查询。ObjectQuery 还实现了一组查询生成器方法,这些方法可用于按顺序构造等效于 Entity SQL 的查询命令。下面是ObjectQuery 的查询生成器方法以及等效的 Entity SQL 语句:
Distinct,Except,GroupBy,Intersect,OfType,OrderBy,Select,SelectValue,Skip,Top,Union,UnionAll,Where
每个查询生成器方法返回 ObjectQuery 的一个新实例。使用这些方法可以构造查询,而查询的结果集基于前面 ObjectQuery 实例序列的操作。下面来看具体的代码片断:
l Execute方法:
using(var edm =new NorthwindEntities())
{
stringesql = "select value c fromNorthwindEntities.Customers as c order by c.CustomerID limit 10";
ObjectQuery<Customers> query = edm.CreateQuery<Customers>(esql);
ObjectResult<Customers> results = query.Execute(MergeOption.NoTracking);
Assert.AreEqual(results.Count(),10);
foreach(Customers cinquery)
Console.WriteLine(c.CustomerID);
}
其中需要说明的是: MergeOption这个枚举类型的参数项,MergeOption有四种值分别是:
l AppendOnly:只追加新实体,不修改以前获取的现有实体。这是默认行为。
l OverwriteChanges: 将 ObjectStateEntry 中的当前值替换为存储区中的值。这将使用服务器上的数据重写在本地所做的更改。
l PreserveChanges:将替换原始值,而不修改当前值。这对于在发生开放式并发异常之后强制成功保存本地值非常有用。
l NoTracking:将不修改ObjectStateManager,不会获取与其他对象相关联的关系,可以改善性能。
l GetResultType方法:返回查询结果的类型信息.例如:
using(var edm =new NorthwindEntities())
{
stringesql = "select value c fromNorthwindEntities.Customers as c order by c.CustomerID limit 10";
ObjectQuery<Customers> query = edm.CreateQuery<Customers>(esql);
Console.WriteLine(query.GetResultType().ToString());
//输出结果为:
//NorthWindModel.Customers
}
l ToTraceString方法:获取当前执行的SQL语句。
l Where
实例代码如下:
using(var edm =new NorthwindEntities())
{
stringesql = "select value c fromNorthwindEntities.Customers as c ";
ObjectQuery<Customers> query1 = edm.CreateQuery<Customers>(esql);
//使用ObjectParameter的写法
query1 = query1.Where("it.CustomerId=@customerid");
query1.Parameters.Add(newObjectParameter("customerid","ALFKI"));
//也可以这样写
//ObjectQuery<Customers>query2 = edm.Customers.Where("it.CustomerID='ALFKI'");
foreach(var cinquery1)
Console.WriteLine(c.CustomerID);
//显示查询执行的SQL语句
Console.WriteLine(query1.ToTraceString());
}
l First/ FirstOrDefault
实例代码如下:
using(var edm =new NorthwindEntities())
{
stringesql = "select value c fromNorthwindEntities.Customers as c order by c.CustomerID limit 10";
ObjectQuery<Customers> query = edm.CreateQuery<Customers>(esql);
Customersc1 = query.First();
Customersc2 = query.FirstOrDefault();
Console.WriteLine(c1.CustomerID);
Assert.IsNotNull(c2);
Console.WriteLine(c2.CustomerID);
}
l Distinct
实例代码如下:
using (varedm =new NorthwindEntities())
{
stringesql = "select value c.City fromNorthwindEntities.Customers as c order by c.CustomerID limit 10";
ObjectQuery<string> query = edm.CreateQuery<string>(esql);
query = query.Distinct();
foreach(string cinquery)
{
Console.WriteLine("City {0}", c);
}
}
l Except:返回两个查询的差集。实例代码如下:
using (varedm =new NorthwindEntities())
{
stringesql1 = "select value c fromNorthwindEntities.Customers as c order by c.CustomerID limit 10";
ObjectQuery<Customers> query1 = edm.CreateQuery<Customers>(esql1);
stringesql2 = "select value c fromNorthwindEntities.Customers as c where c.Country='UK' order by c.CustomerID limit10";
ObjectQuery<Customers> query2 = edm.CreateQuery<Customers>(esql2);
query1 = query1.Except(query2);
foreach (Customers cinquery1)
{
Console.WriteLine(c.Country);
//输出:UK
}
}
l Intersect:返回两个查询的交集。实例代码如下:
using (varedm =new NorthwindEntities())
{
stringesql1 = "select value c fromNorthwindEntities.Customers as c order by c.CustomerID limit 10";
ObjectQuery<Customers> query1 = edm.CreateQuery<Customers>(esql1);
stringesql2 = "select value c from NorthwindEntities.Customersas c where c.Country='UK'order by c.CustomerID limit 10";
ObjectQuery<Customers> query2 = edm.CreateQuery<Customers>(esql2);
query1 =query1.Intersect(query2);
foreach(Customers cinquery1)
{
Console.WriteLine(c.Country);
}
}
l Union/UnionAll:返回两个查询的合集,包括重复项。其中UnionAll必须是相同类型或者是可以相互转换的。
l Include:可通过此方法查询出与相关的实体对象。实例代码如下:
using (varedm =new NorthwindEntities())
{
stringesql1 = "select value c fromNorthwindEntities.Customers as c WHERE c.CustomerID ='HANAR'";
ObjectQuery<Customers> query1 = edm.CreateQuery<Customers>(esql1);
query1 = query1.Include("Orders");
foreach(Customers cinquery1)
{
Console.WriteLine("{0},{1}", c.CustomerID,c.Orders.Count);
//输出:HANAR,14
}
}
l OfType:根据制定类筛选元素创建一个新的类型。此类型是要在实体模型中已定义过的。
l OrderBy
实例代码如下:
using (varedm =new NorthwindEntities())
{
stringesql1 = "select value c fromNorthwindEntities.Customers as c order by c.CustomerID limit 10";
ObjectQuery<Customers> query1 = edm.CreateQuery<Customers>(esql1);
query1.OrderBy("it.country asc,it.city asc");
//也可以这样写
//query1.OrderBy("it.countryasc");
//query1.OrderBy("it.cityasc");
foreach(Customers cinquery1)
{
Console.WriteLine("{0},{1}", c.Country, c.City);
}
}
l Select
实例代码如下:
using (varedm =new NorthwindEntities())
{
stringesql1 = "select value c fromNorthwindEntities.Customers as c order by c.CustomerID limit 10";
ObjectQuery<Customers> query1 = edm.CreateQuery<Customers>(esql1);
ObjectQuery<DbDataRecord> records = query1.Select("it.customerid,it.country");
foreach(DbDataRecord cinrecords)
{
Console.WriteLine("{0},{1}", c[0], c[1]);
}
Console.WriteLine(records.ToTraceString());
//SQL输出:
//SELECTTOP (10)
//1AS [C1],
//[Extent1].[CustomerID]AS [CustomerID],
//[Extent1].[Country]AS [Country]
//FROM[dbo].[Customers] AS [Extent1]
//ORDERBY [Extent1].[CustomerID] ASC
}
l SelectValue
实例代码如下:
using (varedm =new NorthwindEntities())
{
stringesql1 = "select value c fromNorthwindEntities.Customers as c order by c.CustomerID limit 10";
ObjectQuery<Customers> query1 = edm.CreateQuery<Customers>(esql1);
ObjectQuery<string> records = query1.SelectValue<string>("it.customerid");
foreach(string cinrecords)
{
Console.WriteLine("{0}", c);
}
Console.WriteLine(records.ToTraceString());
//SQL输出:
//SELECTTOP (10)
//[Extent1].[CustomerID]AS [CustomerID]
//FROM[dbo].[Customers] AS [Extent1]
//ORDERBY [Extent1].[CustomerID] ASC
}
l Skip/Top
实例代码如下:
using (varedm =new NorthwindEntities())
{
stringesql1 = "select value c fromNorthwindEntities.Customers as c order by c.CustomerID ";
ObjectQuery<Customers> query1 = edm.CreateQuery<Customers>(esql1);
query1 = query1.Skip("it.customerid asc","10");
query1 = query1.Top("10");
foreach(Customers cinquery1)
{
Console.WriteLine("{0}", c.CustomerID);
}
Console.WriteLine(query1.ToTraceString());
//SQL输出:
//SELECTTOP (10)
//[Extent1].[CustomerID]AS [CustomerID]
//FROM[dbo].[Customers] AS [Extent1]
//ORDERBY [Extent1].[CustomerID] ASC
}
本节,简单的介绍一下与ObjectQuery查询相关的语法,我个人觉得查询写法比较多,需要在日常的编程中去发现,在这里就不一一复述了。下节,将介绍EntityClient相关的内容。
Entity Framework学习初级篇6--EntityClient
System.Data.EntityClient 命名空间是 实体框架的 .NET Framework 数据提供程序。EntityClient 提供程序使用存储特定的 ADO.NET 数据提供程序类和映射元数据与实体数据模型进行交互。EntityClient 首先将对概念性实体执行的操作转换为对物理数据源执行的操作。然后再将物理数据源返回的结果集转换为概念性实体。
EntityClient下的类有以下几个:
l EntityConnection
l EntityCommand
l EntityConnectionStringBuilder
l EntityParameter
l EntityDataReader
l EntityParameterCollection
l EntityProviderFactory
l EntityTransaction
从类的名字上看,我们就知道它们的作用是什么了。在此,就不再一一解释了。直接通过实例代码来学习它们。
l EntityConnection:
实例代码1:
stringcon = "name = NorthwindEntities";
using(EntityConnection econn =new EntityConnection(con))
{
stringesql = "Select VALUE c fromNorthwindEntities.Customers as c where c.CustomerID='ALFKI'";
econn.Open();
EntityCommandecmd =new EntityCommand(esql,econn);
EntityDataReaderereader = ecmd.ExecuteReader(CommandBehavior.SequentialAccess);
if(ereader.Read())
{
Console.WriteLine(ereader["CustomerID"]);
}
Console.WriteLine(ecmd.ToTraceString());