Entity Framework 学习中级篇1—EF支持复杂类型的实现
本节,将介绍如何手动构造复杂类型(ComplexType)以及复杂类型的简单操作。
通常,复杂类型是指那些由几个简单的类型组合而成的类型。比如:一张Customer表,其中有FristName和LastName字段,那么对应的Customer实体类将会有FristName和LastName这两个属性。当我们想把FirstName和LastName合成一个名为CustomerName属性时,此时,如果要在EF中实现这个目的,那么我们就需要用到复杂类型。
目前,由于EF不能显示支持复杂类型,所以我们无法在VS里的可视化设计器里面来设计我们需要的复杂类型。所以,我们需要手动修改实体模型,以便使其支持复杂类型的属性。修改的主要步骤有以下几步:
l 产生实体模型
l 修改CSDL文件
l 修改msl文件
l 重新生成模型实体类
在后续的介绍,我使用数据库使用的是NorthWind,并针对Customer表对应的实体类来增加复杂属性Address,其中复杂属性Address由Address,City,Region,Country和PostalCode这个几个组合而成。
下面,介绍具体的操作步骤:
第一步:产生实体模型
实体模型的产生我们可以直接通过在VS可视化设计器来产生(如果不会,请参考《Entity Framework 学习初级篇1--EF基本概况》)。或者使用EdmGen工具来产生(EdmGen工具位于:系统盘符:\WINDOWS\Microsoft.NET\Framework\v3.5下面)。具体步骤就不复述了。
我产生的实体模型文件是:NorthwindEnites.edmx
第二步:修改csdl文件
产生了实体模型后,我们使用记事本或其他文本编辑工具打开实体模型,(小技巧:可以把实体模型后缀.edmx改为.xml,然后把实体模型文件直接拖到VS里面进行修改,这样修改起来比较方便,待修改完毕后,将后缀改回来即可。)
接着,开始手动修改csdl文件,找到模型文件中关于csdl定义的部分,然后找到实体类型名为Customers的定义节,删除原来的Address,City,Region,Country,PostalCode属性定义,然后添加一个名为Address的属性,如下代码所示:
<EntityType Name="Customers">
<Key>
<PropertyRef Name="CustomerID" />
</Key>
<Property Name="CustomerID" Type="String" Nullable="false" MaxLength="5" Unicode="true"FixedLength="true" />
<Property Name="CompanyName" Type="String" Nullable="false" MaxLength="40" Unicode="true"FixedLength="false" />
<Property Name="ContactName" Type="String" MaxLength="30" Unicode="true" FixedLength="false"/>
<Property Name="ContactTitle" Type="String" MaxLength="30" Unicode="true"FixedLength="false" />
<Property Name="Address" Type="NorthwindModel.CommonAddress" Nullable="false"></Property>
<Property Name="Phone" Type="String" MaxLength="24" Unicode="true" FixedLength="false" />
<Property Name="Fax" Type="String" MaxLength="24" Unicode="true" FixedLength="false" />
<NavigationProperty Name="Orders" Relationship="NorthwindModel.FK_Orders_Customers"FromRole="Customers" ToRole="Orders" />
<NavigationProperty Name="CustomerDemographics"Relationship="NorthwindModel.CustomerCustomerDemo" FromRole="Customers" ToRole="CustomerDemographics" />
</EntityType>
接着,需要添加一个名为CommonAddress复杂类型的定义,具体如下代码:
<ComplexType Name="CommonAddress">
<Property Name="Address" Type="String" MaxLength="60" Unicode="true" FixedLength="false" />
<Property Name="City" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
<Property Name="Region" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
<Property Name="PostalCode" Type="String" MaxLength="10" Unicode="true" FixedLength="false"/>
<Property Name="Country" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
</ComplexType>
至此,csdl部分修改完毕。
第三步,修改msl文件:
找到msl部分的定义,修改Customers部分的影射定义。具体代码如下(请注意ComplexProperty节):
<EntitySetMapping Name="Customers">
<EntityTypeMapping TypeName="IsTypeOf(NorthwindModel.Customers)">
<MappingFragment StoreEntitySet="Customers">
<ScalarProperty Name="CustomerID" ColumnName="CustomerID" />
<ScalarProperty Name="CompanyName" ColumnName="CompanyName" />
<ScalarProperty Name="ContactName" ColumnName="ContactName" />
<ScalarProperty Name="ContactTitle" ColumnName="ContactTitle" />
<ComplexProperty Name="Address" TypeName="NorthwindModel.CommonAddress">
<ScalarProperty Name="Address" ColumnName="Address" />
<ScalarProperty Name="City" ColumnName="City" />
<ScalarProperty Name="Region" ColumnName="Region" />
<ScalarProperty Name="PostalCode" ColumnName="PostalCode" />
<ScalarProperty Name="Country" ColumnName="Country" />
</ComplexProperty>
<ScalarProperty Name="Phone" ColumnName="Phone" />
<ScalarProperty Name="Fax" ColumnName="Fax" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
至此,msl部分修改完毕
第四步:重新产生实体类文件。
我们可以使用EmdGen2工具来重新实体类.cs文件。具体操作如下:
将修改好的模型文件(edmx),拷贝到使用edmgen2.exe同目录下,然后在命令行中输入:
Edmgen2 /codegen cs NorthwindEnites.edmx
执行此命令后,会在当前的文件夹下生成一个NorthwindEnites.cs代码文件,也就是实体类的代码文件。将改文件改名为:NorthwindEnites.Designer.cs(这步主要是和edmx对应起来)。
然后,将NorthwindEnites.edmx和NorthwindEnites.Designer.cs文件添加到项目中。
至此,复合类型的修改完毕。
按照同样的修改过程,我们可以给Employees也增加一个Address的复杂类型属性。
接下来,我们看看具体使用代码:
l 查询:
[Test]
public void TestAddress()
{
using (var db = new NorthwindModel.NorthwindEntities1())
{
Console.WriteLine("Get Five customer addresss :");
var cts = db.Customers.Take(5);
foreach (var c in cts)
{
Console.WriteLine("Address:{0},Country:{1},City:{2},PostalCode:{3}", c.Address.Address, c.Address.Country, c.Address.City, c.Address.PostalCode);
}
Console.WriteLine("Get Five Employess address:");
var emp = db.Customers.Take(5);
foreach (var c in emp)
{
Console.WriteLine("Address:{0},Country:{1},City:{2},PostalCode:{3}", c.Address.Address, c.Address.Country, c.Address.City, c.Address.PostalCode);
}
}
}
l 添加:
[Test]
public void AddTest()
{
using (var db = new NorthwindModel.NorthwindEntities1())
{
var customer = new NorthwindModel.Customers
{
CustomerID = "2009",
CompanyName = "Complex Company",
ContactName = "xray2005",
Address = new NorthwindModel.CommonAddress
{
Address = "SiChuan,China",
City = "ChengDou",
Country = "China",
PostalCode = "610041",
Region = "Chenghua"
}
};
db.AddToCustomers(customer);
db.SaveChanges();
var cst = db.Customers.FirstOrDefault(c => c.CustomerID == "2009");
Assert.IsNotNull(cst);
Console.WriteLine("CustomerID:{0},CompanyName:{1},ContactName:{2},City:{3},Country:{4}", cst.CustomerID, cst.CompanyName, cst.ContactName, cst.Address.City, cst.Address.Country);
}
}
l 条件查询:
[Test]
public void QueryTest()
{
using (var db = new NorthwindModel.NorthwindEntities1())
{
var cst = db.Customers.FirstOrDefault(c => c.Address.City == "ChengDou");
Assert.IsNotNull(cst);
Console.WriteLine("CustomerID:{0},CompanyName:{1},ContactName:{2},City:{3},Country:{4}", cst.CustomerID, cst.CompanyName, cst.ContactName, cst.Address.City, cst.Address.Country);
}
}
最后,补充说明:
1, 在VS的可视化设计器里,不支持复杂类型,所以修改后无法再在可视化设计器里修改模型(edmx文件)。
2, 复杂类型不能单独存在,它必须和某一实体相关起来。
3, 复杂类型不能包含导航属性,如导航到实体或实体集。
4, 复杂类型具有内部结构但没有 Key(主键) 属性的数据类型
下面是示例代码和EdmGen2工具的连接。
Entity Framework 学习中级篇1—EF支持复杂类型的实现的更多相关文章
- Entity Framework 学习中级篇3—存储过程(中)
目前,EF对存储过程的支持并不完善.存在以下问题: l EF不支持存储过程返回多表联合查询的结果集. l EF仅支持返回返回某个表的全部字段,以便转换成对应的实体.无法 ...
- Entity Framework 学习中级篇2—存储过程(上)
目前,EF对存储过程的支持并不完善.存在以下问题: l EF不支持存储过程返回多表联合查询的结果集. l EF仅支持返回返回某个表的全部字段,以便转换成对应的实体.无法 ...
- Entity Framework 学习中级篇4—存储过程(下)
在EF中,各个实体的插入.更新和删除也都通过使用存储过程来完成,以便提高点性能.这个类似于数据集.其步骤是:先定义存储过程,然后在VS的可视化设计器,设置存储过程映射即可. 下面,以为Supplier ...
- Entity Framework学习初级篇2
Entity Framework 学习初级篇2--ObjectContext.ObjectQuery.ObjectStateEntry.ObjectStateManager类的介绍 本节,简单的介绍E ...
- Entity Framework 学习初级篇1--EF基本概况
转自:http://www.cnblogs.com/Tally/archive/2012/09/14/2685011.html 最近在学习研究微软的EF,通过这时间的学习研究,感觉这个EF目前来说还不 ...
- Entity Framework学习初级篇1--EF基本概况《转》
最近在学习研究微软的EF,通过这时间的学习研究,感觉这个EF目前来说还不是很完善,半成品.不过,据说在.Net4.0中,微软将推荐使用此框架,并会有所改善.而且,现在基本上所有数据库均提供了对EF的支 ...
- Entity Framework 学习初级篇--基本操作:增加、更新、删除、事务(转)
摘自:http://www.cnblogs.com/xray2005/archive/2009/05/17/1458568.html 本节,直接写通过代码来学习.这些基本操作都比较简单,与这些基本操作 ...
- Entity Framework 学习初级篇7--基本操作:增加、更新、删除、事务
本节,直接写通过代码来学习.这些基本操作都比较简单,与这些基本操作相关的内容在之前的1至6节基本介绍完毕. l 增加: 方法1:使用AddToXXX(xxx)方法:实例代码如下: ...
- Entity Framework 学习高级篇1—改善EF代码的方法(上)
本节,我们将介绍一些改善EF代码的相关方法,如NoTracking,GetObjectByKey, Include等. l MergeOption.NoTracking 当我们只需要读 ...
随机推荐
- buffer小解
Buffer代表一个缓冲区,存储二进制数据,是字节流 创建: 创建Buffer有4种方式: 1.new Buffer(size) 以字节为单位创建指定大小的Buffer eg: var buf= ne ...
- dedecms 自定义标签的方法
function lib_demotest(&$ctag,&$refObj) { global $dsql,$envs; //属性处理 $attlist="row|12,ti ...
- Git单独checkout子目录
http://schacon.github.io/git/git-read-tree.html#_sparse_checkout Existing Repository If you already ...
- 《JavaScript高级程序设计》读书笔记 ---操作符二
关系操作符 小于(<).大于(>).小于等于(<=)和大于等于(>=)这几个关系操作符用于对两个值进行比较,比较的规则与我们在数学课上所学的一样.这几个操作符都返回一个布尔值, ...
- windows做时间服务器,linux和windows时间同步
找了很多的资料,都没有windows做时间服务,linux同步windows的时间的,最后自己找了一些软件,终于搞定了,写出来给大家共享,以免大家多走弯路 首先在http://www.meinberg ...
- 第五节 面向连接传输:TCP
第五节 面向连接传输:TCP TCP概述RFCs:793,1122,1323,2018,2581 点对点: 一个发送方,一个接收方 可靠,按序的字节流: 无“报文边界”,无结构但有 ...
- 理解 php 中& 引用
php中引用&的真正理解-变量引用.函数引用.对象引用 php的引用(就是在变量或者函数.对象等前面加上&符号) //最重要就是 删除引用的变量 ,只是引用的变量访问不了,但是内容并没 ...
- JavaScript高级程序设计:第十二章
DOM1级主要定义的是HTML和XML文档的底层结构.DOM2和DOM3级则在这个结构的基础上引入了更多的交互能力,也支持了更高级的XML特性.为此DOM2和DOM3级分为许多模块,这些模块如下: D ...
- Autofac 组件、服务、自动装配(2)
一.组件 创建出来的对象需要从组件中来获取,组件的创建有如下4种(延续第一篇的Demo,仅仅变动所贴出的代码)方式: 1.类型创建RegisterType AutoFac能够通过反射检查一个类型,选择 ...
- Linq第一讲
在说LINQ之前必须先说说几个重要的C#语言特性 一:与LINQ有关的语言特性 1.隐式类型 (1)源起 在隐式类型出现之前,在声明一个变量的时候, 总是要为一个变量指定他的类型甚至在foreach一 ...