Entity Framework.docx
《Entity Framework.docx》由会员分享,可在线阅读,更多相关《Entity Framework.docx(31页珍藏版)》请在冰豆网上搜索。
EntityFramework
EntityDataModel(EDM)深入分析,Part1
EntityDataModel是.NETFrameworkv3.5SP1引入的新功能,比LinqToSQL更加强大的ORM,让开发人员只需要着眼于领域对象模型的开发,而不需要考虑它们是如何与关系数据库交互。
本系列文章逐步深入介绍如下内容:
EDMXSchema文件、ModelBrowser、映射关系、产生的实体类(Generatedentityclasses)、文档(Documentation)等等。
1.EDMXSchema文件
可以将EDMX作为XML文件打开,你会发现该文件包含3个主要部分。
ConceptualModels(CSDL)
StorageModels(SSDL)
Mapping(MSL)
一般情况下,你没有必要手动修改EDMX-XML文件。
可视化的EDM设计器、MappingDetails窗口和ModelBrowser窗口包含有上述3个部分,并非常友好地显示整个EntityDataModel模型。
当你编译项目时,MSBuild将从EDMX文件提取CSDL/SSDL/MSL内容,并放置3个独立的XML文件到项目的输出目录。
2.ModelBrowser窗口
ModelBrowser窗口以可视的树形图显示概念模型和存储模型。
3.Mappingdetails窗口
EDM设计器也提供了一个不错的MappingDetails窗口,包含2个视图。
MapEntitytoTables/View
这一视图显示了数据库中所有字段和相应实体中的属性,可以用来查看和编辑EDM的映射关系。
MapEntitytoFunctions
这一视图用来选择一个特定的存储过程来插入、更新或删除Entity实例。
4.生成的实体类(GeneratedEntityClasses)
除了上述的XMLSchema文件外,EDM向导也生成了实体类。
下一步仔细分析.Designer.cs文件中的实体类,并和LINQtoSQL中的类进行比较。
1)比较LINQtoSQLclass和EDMEntityObjectclass
//LINQtoSQL
[Table(Name="dbo.Employees")]
publicpartialclassEmployee:
INotifyPropertyChanging,INotifyPropertyChanged
EDM类则是以不同的attributes,并且总是继承EntityObject或ComplexObject类。
EntityObject类提供了变更跟踪和关系管理。
//EntityDataModel
[global:
:
System.Data.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="NorthwindModel",Name="Employee")]
[global:
:
System.Runtime.Serialization.DataContractAttribute()]
[global:
:
System.Serializable()]
publicpartialclassEmployee:
global:
:
System.Data.Objects.DataClasses.EntityObject
2)比较LINQtoSQLentityconstructor和EDMCreatemethod
//LINQtoSQL
publicEmployee()
{
this._Employees=newEntitySet(newAction(this.attach_Employees),newAction(this.detach_Employees));
this._EmployeeTerritories=newEntitySet(newAction(this.attach_EmployeeTerritories),
newAction(this.detach_EmployeeTerritories));
this._Orders=newEntitySet(newAction(this.attach_Orders),newAction(this.detach_Orders));
this._Employee1=default(EntityRef);
OnCreated();
}
EDM没有生成上述LINQtoSQL的构造函数,而是创建了一个特定的Create方法,并提供了所有必需属性(notnullable)的输入参数。
//EntityDataModel
publicstaticEmployeeCreateEmployee(intemployeeID,stringlastName,stringfirstName)
{
Employeeemployee=newEmployee();
employee.EmployeeID=employeeID;
employee.LastName=lastName;
employee.FirstName=firstName;
returnemployee;
}
3)比较LINQtoSQL和EDM:
实体属性(entityproperty)
//LINQtoSQL
[Column(Storage="_EmployeeID",AutoSync=AutoSync.OnInsert,DbType="IntNOTNULLIDENTITY",IsPrimaryKey=true,IsDbGenerated=true)]
publicintEmployeeID
{
get
{
returnthis._EmployeeID;
}
set
{
if((this._EmployeeID!
=value))
{
this.OnEmployeeIDChanging(value);
this.SendPropertyChanging();
this._EmployeeID=value;
this.SendPropertyChanged("EmployeeID");
this.OnEmployeeIDChanged();
}
}
}
尽管EDM公有属性(publicproperty)的attribute是不同的,但get和set基本是一样的。
//EntityDataModel
[global:
:
System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true,IsNullable=false)]
[global:
:
System.Runtime.Serialization.DataMemberAttribute()]
publicintEmployeeID
{
get
{
returnthis._EmployeeID;
}
set
{
this.OnEmployeeIDChanging(value);
this.ReportPropertyChanging("EmployeeID");
this._EmployeeID=global:
:
System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
this.ReportPropertyChanged("EmployeeID");
this.OnEmployeeIDChanged();
}
}
4)比较LINQtoSQLTable和EDMObjectQuery
//LINQtoSQL
publicSystem.Data.Linq.TableEmployees
{
get
{
returnthis.GetTable();
}
}
在LINQtoSQL中,调用GetTable方法,返回实体集合。
在EDM中,通过ObjectServicescompoment执行EntitySQL查询,返回EntityType的计划EntitySet。
//EntityDataModel
[global:
:
System.ComponentModel.BrowsableAttribute(false)]
publicglobal:
:
System.Data.Objects.ObjectQueryEmployees
{
get
{
if((this._Employees==null))
{
this._Employees=base.CreateQuery("[Employees]");
}
returnthis._Employees;
}
}
privateglobal:
:
System.Data.Objects.ObjectQuery_Employees;
5)比较LINQtoSQLDataContext和EDMObjectContext
//LINQtoSQL
[System.Data.Linq.Mapping.DatabaseAttribute(Name="Northwind")]
publicpartialclassNorthwindDataContext:
System.Data.Linq.DataContext
EDM有一个类似于LINQtoSQLDataContext的ObjectContext类,ObjectContext类是负责与EDM中实体类型交互的基本类。
ObjectContext用来创建数据库连接、检索数据、持久化对象、以及对数据库的插入、更新和删除操作。
//EntityDataModel
publicpartialclassNorthwindEntities:
global:
:
System.Data.Objects.ObjectContext
ObjectContext的连接字符串指向元数据(CSDL/SSDL/MSL文件)和数据源(数据库连接字符串)。
connectionString="metadata=.NorthwindModel.csdl|.NorthwindModel.ssdl|.NorthwindModel.msl;
provider=System.Data.SqlClient;providerconnectionstring="
DataSource=SQLEXPRESS;InitialCatalog=Northwind;IntegratedSecurity=True;MultipleActiveResultSets=True""
5.Documentation属性
EDM中的实体类型(EntityTypes)、关联和属性有一个Documentation属性,对LINQtoSQL而言,这是一个新的属性。
Documentation属性将更新生成的partial实体类的XML注释,可以用来生成代码文档的帮助文件。
///
///EmployeeentitywhichcorrespondswiththeNorthwind.Employeestable
///
///
///EmployeeID
///
[global:
:
System.Data.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="NorthwindModel",Name="Employee")]
[global:
:
System.Runtime.Serialization.DataContractAttribute()]
[global:
:
System.Serializable()]
publicpartialclassEmployee:
global:
:
System.Data.Objects.DataClasses.EntityObject
英文链接:
1.ADO.NETEntityFramework&LINQtoEntities,
http:
//www.scip.be/index.php?
Page=ArticlesNET12
EntityDataModel(EDM)深入分析,Part2
实体SQL(EntitySQL),它是一种新的SQL语言,其中加入了之前的SQL语言并不支持的基于概念的查询功能。
ESQL扩展现有SQL语言的方式与EDM扩展数据库中所使用的关系模型的方式十分类似。
此外,ESQL未绑定到任何特定于后台数据库的语法,因此可一次性编写查询(和/或应用程序),无论针对的是哪个后台数据库都无影响。
EntitySQL是基于文本的、面向集合的、延后绑定的查询语言,也受到了T-SQL的影响。
可以使用EntitySQL创建对EDM的查询,EntitySQL既可以通过ObjectServicescomponents来执行,也可以通过EntityClientcomponents来执行。
EntitySQL设计的非常灵活,因此也变得有些复杂。
本篇文章侧重于不同的查询技术,仅仅使用简单的查询,不包含复杂的条件、关联和聚合公式。
本系列文章上一篇:
EntityDataModel(EDM)深入分析,Part1
1.使用ObjectQuery查询返回实体类型(EntityType)集合
下面演示如何执行EntitySQL查询,返回实体类型的实例集合。
1)首先创建NorthwindObjectContext实例。
2)EntitySQL语句本身是字符串表达式,在大多数情况下,由SELECT-FROM查询语句组成。
在SELECT语句中使用VALUE关键字来表示返回的实体是一条数据行。
3)使用ObjectServicescomponents执行查询。
调用ObjectContext的工厂方法CreateQuery(),创建一个ObjectQuery对象,该对象表示对存储数据源的查询,查询表达式为EntitySQL语句。
4)EntityFramework实体框架采用延迟装载(Deferredloading)。
因此只有在显式需要数据时,才真正执行SQL语句。
在这种情况下,在ForEach第一次迭代时,才执行查询语句。
NorthwindEntitiescontext=newNorthwindEntities();
varsql="SELECTVALUEempFROMNorthwindEntities.EmployeesASemp";
varquery=context.CreateQuery(sql);
foreach(varempinquery)
Console.WriteLine("{0}{1}{2}{3}",emp.EmployeeID,emp.FirstName,emp.LastName,emp.Country);
除了使用工厂方法CreateQuery外,也可以直接创建ObjectQuery对象实例,并传入ObjectContext参数,示例代码如下:
NorthwindEntitiescontext=newNorthwindEntities();
varsql="NorthwindEntities.Employees";
ObjectQueryquery=newObjectQuery(sql,context);
foreach(varempinquery)
Console.WriteLine("{0}{1}{2}{3}",emp.EmployeeID,emp.FirstName,emp.LastName,emp.Country);
下面增加一个WHERE条件:
varsql="SELECTVALUEempFROMNorthwindEntities.EmployeesASemp"+
"WHEREemp.Country='USA'";
varquery=context.CreateQuery(sql);
2.带参数的ObjectQuery查询
参数变量是在EntitySQL外定义的,在查询语句中需要以@符合作为前缀定义变量名。
参数定义为ObjectParameter对象,然后增加到ObjectQuery实例中。
下面增加一个Country变量:
varsql="SELECTVALUEempFROMNorthwindEntities.EmployeesASemp"+
"WHEREemp.Country=@country";
varquery=context.CreateQuery(sql);
query.Parameters.Add(newObjectParameter("country","USA"));
同样以ObjectQuery示例对象实现这一功能:
varsql="SELECTVALUEempFROMNorthwindEntities.EmployeesASemp"+
"WHEREemp.Country=@country";
ObjectQueryquery=newObjectQuery(sql,context);
query.Parameters.Add(newObjectParameter("country","USA"));
ObjectParameter对象也可以直接传入CreateQuery方法:
varsql="SELECTVALUEempFROMNorthwindEntities.EmployeesASemp"+
"WHEREemp.Country=@country";
varquery=context.CreateQuery(sql,newObjectParameter("country","USA"));
第三种方法的是使用Where扩展方法,使用关键字it指向当前的查询语句:
varsql="SELECTVALUEempFROMNorthwindEntities.EmployeesASemp";
varquery=context.CreateQuery(sql)
.Where("it.Country=@country",newObjectParameter("country","USA"));
3.ObjectQuery查询返回基本类型(PrimitiveType)
除了返回实体类型外,也可以返回基本类型集合,因此需要确保SELECT语句仅仅返回1个值,同时也需要在CreateQuery方法中指定需要返回的基本类型。
varsql="SELECTVALUEemp.EmployeeIDFROMNorthwindEntities.EmployeesASemp"+
"WHEREemp.Country=@country";
varquery=context.CreateQuery(sql,newObjectParameter("Country","USA"));
foreach(varidinquery)
Console.WriteLine("{0}",id.ToString());
另一示例脚本:
varsql="SELECTVALUEemp.CountryFROMNorthwindEntities.EmployeesASemp"+
"WHEREemp.EmployeeID=@id";
varquery=context.CreateQuery(sql,newObjectParameter("id",1));
Console.WriteLine(query.First());
除了使用EntitySQL外,你也能使用查询构造(QueryBuilder)方法实现相同的效果。
EntitySQL提供了SelectValue方法,可以提过隐式的行构造器,仅仅返回指定的列。
stringcountry=context.Employees.SelectValue("it.Country",newObjectParameter("id",1)).First();
Console.WriteLine(country);
4.ObjectQuery查询返回匿名类型
也有可能需要调整数据,并使用ObjectQuery查询返回匿名类型。
在CreateQuery方法中,改变SELECT语句并使用DbDataRecord类,DbDataReader类在.NET1.0引入,它提供了对任何枚举类型的数据绑定支持。
varsql="SELECTemp.LastName,emp.FirstName"+
"FROMNorthwindEntities.EmployeesASemp";
varquery=context.CreateQuery(