收藏 分销(赏)

Entity-Framework.doc

上传人:仙人****88 文档编号:11895684 上传时间:2025-08-19 格式:DOC 页数:46 大小:376KB 下载积分:10 金币
下载 相关 举报
Entity-Framework.doc_第1页
第1页 / 共46页
Entity-Framework.doc_第2页
第2页 / 共46页


点击查看更多>>
资源描述
Entity Data Model (EDM) 深入分析, Part 1 Entity Data Model是.NET Framework v3.5 SP1引入的新功能,比Linq To SQL更加强大的ORM,让开发人员只需要着眼于领域对象模型的开发,而不需要考虑它们是如何与关系数据库交互。本系列文章逐步深入介绍如下内容:EDMX Schema 文件、Model Browser、映射关系、产生的实体类(Generated entity classes)、文档(Documentation)等等。   1. EDMX Schema 文件   可以将EDMX作为XML文件打开,你会发现该文件包含3个主要部分。 Conceptual Models (CSDL) Storage Models (SSDL) Mapping (MSL)   一般情况下,你没有必要手动修改EDMX -XML文件。可视化的EDM 设计器、Mapping Details窗口和Model Browser 窗口包含有上述3个部分,并非常友好地显示整个Entity Data Model模型。   当你编译项目时,MSBuild 将从EDMX文件提取CSDL/SSDL/MSL内容,并放置3个独立的XML文件到项目的输出目录。   2. Model Browser 窗口   Model Browser窗口以可视的树形图显示概念模型和存储模型。      3. Mapping details 窗口   EDM设计器也提供了一个不错的Mapping Details 窗口,包含2个视图。   Map Entity to Tables / View   这一视图显示了数据库中所有字段和相应实体中的属性,可以用来查看和编辑EDM的映射关系。    Map Entity to Functions   这一视图用来选择一个特定的存储过程来插入、更新或删除Entity实例。      4. 生成的实体类(Generated Entity Classes)   除了上述的XML Schema文件外,EDM向导也生成了实体类。下一步仔细分析.Designer.cs文件中的实体类,并和LINQ to SQL中的类进行比较。   1) 比较 LINQ to SQL class 和 EDM EntityObject class // LINQ to SQL [Table(Name="dbo.Employees")] public partial class Employee : INotifyPropertyChanging, INotifyPropertyChanged   EDM类则是以不同的attributes,并且总是继承EntityObject或ComplexObject 类。EntityObject 类提供了变更跟踪和关系管理。 // Entity Data Model [global::System.Data.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="NorthwindModel", Name="Employee")] [global::System.Runtime.Serialization.DataContractAttribute()] [global::System.Serializable()] public partial class Employee : global::System.Data.Objects.DataClasses.EntityObject   2) 比较LINQ to SQL entity constructor 和 EDM Create method // LINQ to SQL public Employee() { this._Employees = new EntitySet<Employee>(new Action<Employee>(this.attach_Employees), new Action<Employee>(this.detach_Employees)); this._EmployeeTerritories = new EntitySet<EmployeeTerritory>(new Action<EmployeeTerritory>(this.attach_EmployeeTerritories),   new Action<EmployeeTerritory>(this.detach_EmployeeTerritories)); this._Orders = new EntitySet<Order>(new Action<Order>(this.attach_Orders), new Action<Order>(this.detach_Orders)); this._Employee1 = default(EntityRef<Employee>); OnCreated(); }   EDM没有生成上述LINQ to SQL的构造函数,而是创建了一个特定的Create方法,并提供了所有必需属性(not nullable)的输入参数。 // Entity Data Model public static Employee CreateEmployee(int employeeID, string lastName, string firstName) {   Employee employee = new Employee();   employee.EmployeeID = employeeID;   employee.LastName = lastName;   employee.FirstName = firstName;   return employee; }   3) 比较LINQ to SQL 和 EDM : 实体属性(entity property) // LINQ to SQL [Column(Storage="_EmployeeID", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)] public int EmployeeID { get {   return this._EmployeeID; } set {  if ((this._EmployeeID != value))   {    this.OnEmployeeIDChanging(value);    this.SendPropertyChanging();    this._EmployeeID = value;    this.SendPropertyChanged("EmployeeID");    this.OnEmployeeIDChanged();   } } }   尽管EDM公有属性(public property)的attribute是不同的,但get和set 基本是一样的。 // Entity Data Model [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] [global::System.Runtime.Serialization.DataMemberAttribute()] public int EmployeeID {   get   {     return this._EmployeeID;   }   set   {     this.OnEmployeeIDChanging(value);     this.ReportPropertyChanging("EmployeeID");     this._EmployeeID = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);     this.ReportPropertyChanged("EmployeeID");     this.OnEmployeeIDChanged();   } } 4) 比较LINQ to SQL Table 和 EDM ObjectQuery // LINQ to SQL public System.Data.Linq.Table<Employee> Employees { get {   return this.GetTable<Employee>(); } }   在LINQ to SQL中,调用GetTable 方法,返回实体集合。在EDM中,通过Object Services compoment 执行Entity SQL 查询,返回EntityType的计划EntitySet。 // Entity Data Model [global::System.ComponentModel.BrowsableAttribute(false)] public global::System.Data.Objects.ObjectQuery<Employee> Employees {   get   {     if ((this._Employees == null))     {       this._Employees = base.CreateQuery<Employee>("[Employees]");     }     return this._Employees;   } } private global::System.Data.Objects.ObjectQuery<Employee> _Employees;   5) 比较LINQ to SQL DataContext 和 EDM ObjectContext // LINQ to SQL [System.Data.Linq.Mapping.DatabaseAttribute(Name="Northwind")] public partial class NorthwindDataContext : System.Data.Linq.DataContext   EDM有一个类似于LINQ to SQL DataContext 的ObjectContext类,ObjectContext 类是负责与EDM 中实体类型交互的基本类。ObjectContext用来创建数据库连接、检索数据、持久化对象、以及对数据库的插入、更新和删除操作。 // Entity Data Model public partial class NorthwindEntities : global::System.Data.Objects.ObjectContext ObjectContext的连接字符串指向元数据(CSDL/SSDL/MSL 文件)和数据源(数据库连接字符串)。 connectionString="metadata=.NorthwindModel.csdl|.NorthwindModel.ssdl|.NorthwindModel.msl; provider=System.Data.SqlClient;provider connection string=&quot; Data Source=SQLEXPRESS; Initial Catalog=Northwind; Integrated Security=True; MultipleActiveResultSets=True&quot;"   5. Documentation 属性   EDM中的实体类型(EntityTypes)、关联和属性有一个Documentation属性,对LINQ to SQL而言,这是一个新的属性。      Documentation属性将更新生成的partial实体类的XML注释,可以用来生成代码文档的帮助文件。 /// <summary> /// Employee entity which corresponds with the Northwind.Employees table /// </summary> /// <KeyProperties> /// EmployeeID /// </KeyProperties> [global::System.Data.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="NorthwindModel", Name="Employee")] [global::System.Runtime.Serialization.DataContractAttribute()] [global::System.Serializable()] public partial class Employee : global::System.Data.Objects.DataClasses.EntityObject   英文链接:   1. ADO.NET Entity Framework & LINQ to Entities,   http://www.scip.be/index.php?Page=ArticlesNET12 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"]); Entity Data Model (EDM) 深入分析, Part 3 EntityClient   实体框架(Entity Framework)在ADO.NET 3.5 提供程序的基础上引入新的 ADO.NET 提供程序 EntityClient。EntityClient 看上去与之前使用的 ADO.NET 提供程序非常类似,它将提供第一个抽象,可允许开发人员使用标准的 Connection、Command 和 DataReader 对象依照 EDM 执行查询。它还会将映射域模型所需的客户端视图引擎(根据 EDM 定义的)添加到底层关系数据库架构。必要时,EntityClient 可借助 ESQL 查询字符串让开发人员以行和列的形式处理实体,而不必生成类来表示概念架构。   1. EntityCommand 查询返回实体类型   Entity SQL也可以通过EntityClient 来执行,尽管代码比较啰嗦,但是在某些情况下,也是优点。   1) 首先创建EntityConnection,重用Northwind data context 的连接字符串,并打开连接。   2) 创建 EntityCommand 对象,并传入Entity SQL语句和数据库连接对象。   3) 创建DbDataReader对象,并循环读取返回的结果集。 NorthwindEntities context = new NorthwindEntities();   EntityConnection conn = new EntityConnection(context.Connection.ConnectionString); conn.Open();   var sql = "SELECT VALUE emp FROM NorthwindEntities.Employees AS emp"; EntityCommand cmd = new EntityCommand(sql, conn);   DbDataReader reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess); while (reader.Read()) {  Console.WriteLine("{0} {1} {2} {3}", reader["EmployeeID"], reader["LastName"],     reader["FirstName"], reader["Country"]); } 当时使用SequentialAccess的DbDataReader时,需要小心访问数据,务必有序的读取。   如你改变成员的顺序,将抛出InvalidOperationException 异常 - "Attempt to read from column ordinal '0' is not valid. With CommandBehavior.SequentialAccess, you may only read from column ordinal '2' or greater."   Console.WriteLine("{0} {1} {2} {3}", reader["LastName"], reader["EmployeeID"],  reader["FirstName"], reader["Country"]);   2. EntityCommand 查询返回匿名类型   采用相同的技术可以实现返回匿名类型。 EntityConnection conn = new EntityConnection(context.Connection.ConnectionString); conn.Open();   var sql = "SELECT emp.LastName, emp.FirstName " +           "FROM NorthwindEntities.Employees AS emp"; EntityCommand cmd = new EntityCommand(sql, conn);   DbDataReader reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess); while (reader.Read()) {  Console.WriteLine("{0} {1}", reader["LastName"], reader["FirstName"]); }   3. EntityCommand 带参数查询   EntityCommand 带参数也比较容易,在Entity SQL字符串中参数名称以@作为前缀,接着创建EntityParameter对象,并增加到EntityCommand 的Parameters集合内。 EntityConnection conn = new EntityConnection(context.Connection.ConnectionString); conn.Open();   var sql = "SELECT VALUE emp FROM NorthwindEntities.Employees AS emp " +           "WHERE emp.Country = @country"; EntityCommand cmd = new EntityCommand(sql, conn);   EntityParameter param = new EntityParameter("country", DbType.String);   param.Value = "USA"; cmd.Parameters.Add(param);   DbDataReader reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess); while (reader.Read()) {  Console.WriteLine("{0} {1} {2} {3}", reader["EmployeeID"], reader["LastName"],     reader["FirstName"], reader["Country"]); }  LINQ to Entities   LINQ是在.NET v3.5 引入的新技术。相对于前面的Entity SQL而言,我更偏爱LINQ to entities。LINQ查询虽然有一些局限,但是LINQ更容易、更自然,此外,还支持强类型,因此智能提示能帮助编写LINQ查询脚本。   LINQ to Entities 与LINQ to Objects和LINQ to SQL 基本一样,因此下面简单演示2个基本的LINQ to Entities的查询。   1. LINQ 带参数查询 NorthwindEntities context = new NorthwindEntities();   string country = "USA"; var query = from e in context.Employees             where e.Country == country             select e;   foreach (var emp in query)  Console.WriteLine("{0} {1} {2} {3}", emp.EmployeeID, emp.FirstName, emp.LastName, emp.Country);   2. LINQ 查询返回匿名类型 NorthwindEntities context = new NorthwindEntities();   var query = from e in context.Employees             select new { e.LastName, e.FirstName };   foreach (var emp in query)  Console.WriteLine("{0} {1}", emp.LastName, emp.FirstName);   这篇文章对Entity Data Model 和Entity Framework 提供了各种查询技术进行了简单的介绍,希望对你有帮助。下一篇文章将介绍更高级的 Entity SQL 查询技术、查看SQL 语句、eager loading、变更跟踪、并发… 等等。 ADO.NET Entity Framework 深入分析, Part 4 Entity Data Model 是一个概念模型,所有Entity SQL和LINQ to Entities 查询将最终转化为T-SQL的脚本,从数据库中查询数据。这里演示了几种方法来查看生成的T-SQL,有助于Debug或分析问题。   1. 使用SQL Server Profiler 工具   与LINQ to SQL比较而言,ObjectContext 类没有提供Log属性或者通用的log机制,因此,无法在Visual Studio 中跟踪所有的T-SQL语句。   如果你想查看所有执行的T-SQL语句,你需要使用SQL Server的Profiler 工具,关于具体如何使用SQL Server Profiler工具,请参考如下文章:   SQL Profiler: Features, functions and setup in SQL Server 2005      2. ToTraceString 方法   另外一种方法去查看生成的T-SQL语句的方法,包括 EntityCommand和ObjectQuery类都有一个ToTraceString() 方法。在一些情况下,可以用来查看内部到底生成什么SQL脚本,而不必一定要使用SQL Server Profiler 工具。需要注意的是:ToTraceString() 方法实际上没有执行查询操作,仅仅是转化查询为SQL脚本。   通过增加一个断点,你可以轻松查看SQL脚本,需要记住的是:事先需要打开数据库连接,否则会抛出InvalidOperationException 异常(Execution of the command requires an open and available connection. The connection’s current state is closed.)
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服