EF支持复杂类型的实现
本节,将介绍如何手动构造复杂类型(ComplexType)以及复杂类型的简单操作。
通常,复杂类型是指那些由几个简单的类型组合而成的类型。比如:一张Customer表,其中有FristName和LastName字段,那么对应的Customer实体类将会有FristName和LastName这两个属性。当我们想把FirstName和LastName合成一个名为CustomerName属性时,此时,如果要在EF中实现这个目的,那么我们就需要用到复杂类型。
目前,由于EF不能显示支持复杂类型,所以我们无法在VS里的可视化设计器里面来设计我们需要的复杂类型。所以,我们需要手动修改实体模型,以便使其支持复杂类型的属性。修改的主要步骤有以下几步:
1> 产生实体模型
2> 修改CSDL文件
3> 修改msl文件
4> 重新生成模型实体类
在后续的介绍,我使用数据库使用的是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的复杂类型属性。
接下来,我们看看具体使用代码:
> 查询:
- public void TestAddress()
- {
- using (var db = new NorthwindModel.NorthwindEntities1())
- {
- Console.WriteLine("Get Five customer addresss :");
- var cts = db.Customers.Take();
- 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();
- 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);
- }
- }
- }
> 添加:
- public void AddTest()
- {
- using (var db = new NorthwindModel.NorthwindEntities1())
- {
- var customer = new NorthwindModel.Customers
- {
- CustomerID = "",
- CompanyName = "Complex Company",
- ContactName = "xray2005",
- Address = new NorthwindModel.CommonAddress
- {
- Address = "SiChuan,China",
- City = "ChengDou",
- Country = "China",
- PostalCode = "",
- Region = "Chenghua"
- }
- };
- db.AddToCustomers(customer);
- db.SaveChanges();
- var cst = db.Customers.FirstOrDefault(c => c.CustomerID == "");
- 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);
- }
- }
> 条件查询:
- 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(主键) 属性的数据类型
EF支持复杂类型的实现的更多相关文章
- Entity Framework 学习中级篇1—EF支持复杂类型的实现
本节,将介绍如何手动构造复杂类型(ComplexType)以及复杂类型的简单操作. 通常,复杂类型是指那些由几个简单的类型组合而成的类型.比如:一张Customer表,其中有FristName和Las ...
- EF学习笔记-2 EF之支持复杂类型的实现
使用过.NET的小伙伴们知道,在我们的实体模型中,除了一些简单模型外,还有一些复杂类型,如几个简单的类型组合而成的类型:而EF除了在实现基本的增删改查之外,也支持复杂类型的实现. 那么如何手动构造复杂 ...
- 实体类的枚举属性--原来支持枚举类型这么简单,没有EF5.0也可以
通常,我们都是在业务层和界面层使用枚举类型,这能够为我们编程带来便利,但在数据访问层,不使用枚举类型,因为很多数据库都不支持,比如我们现在用的SqlServer2008就不支持枚举类型的列,用的时候也 ...
- EF里Guid类型数据的自增长、时间戳和复杂类型的用法
通过前两章Lodging和Destination类的演示,大家肯定基本了解Code First是怎么玩的了,本章继续演示一些很实用的东西.文章的开头提示下:提供的demo为了后面演示效果,前面代码有些 ...
- 让Xcode的控制台支持LLDB类型的打印
这个技巧个人认为非常有用 当Xcode在断点调试的时候,在控制台中输入 po self.view.frame 类似这样的命令会挂掉,不信可以亲自去试试(Xcode7 以后支持LLDB类型的打印) 那么 ...
- HttpWebRequest.AddRange 支持long类型
很久很久以前,在哪个FAT32格式还流行的年代,文件大小普遍还没超过4G的年代,.Net已经出来了. 而那时候.Net实现的HTTP断点续传协议,还没预料到如此普及(我猜的).那时候的HttpWebR ...
- python操作Redis安装、支持存储类型、普通连接、连接池
一.python操作redis安装和支持存储类型 安装redis模块 pip3 install redis 二.Python操作Redis之普通连接 redis-py提供两个类Redis和Strict ...
- 游戏开发中IIS常见支持MIME类型文件解析
游戏开发中IIS常见支持MIME类型文件解析 .apkapplication/vnd.android .ipaapplication/vnd.iphone .csbapplication/octet- ...
- json序列化时定制支持datetime类型,和到中文让他保留中文形式
json序列化时,可以处理的数据类型有哪些?如何定制支持datetime类型 自定义时间序列化转换器 import json from json import JSONEncoder from dat ...
随机推荐
- 局域网内Linux服务器时间同步
局域网内Linux服务器时间同步 1.将一台能够上网的服务器作为时间服务器: # /usr/bin/rdate -s time-b.timefreq.bldrdoc.gov //将时间服务器与互 ...
- SAP一句话入门 .
SD是Sales and Distribution的简称.在SAP系统中,销售与分销模块处在供应链下游,关注从客户订单到向客户收款的全过程. SD模块中的Sales好理解,而Distribution却 ...
- javascript中的function对象
function对象都是Function的实例: > Object.getOwnPropertyNames(Function) [ 'length', 'name', 'arguments', ...
- iOS 开发 NSLog调试小技巧
NSLog其实是一个非常损耗性能的东西,当你在开发了很长时间的一个项目中,想必为了方便调试,里面会有很多的NSLog输出,为了优化性能,同时又方便调试,可以在pch中定义一个宏,既可以替换原有的NSL ...
- iOS不勾选设置,实现某个界面强制横屏
1.在不勾选横屏的前提下,实现某一个界面横屏显示,比如播放视频.图表显示等. 2.只能Present跳转,Push会无效. 3.实现代码 在需要横屏的VC里,添加如下代码 #pragma mark 强 ...
- PAT 1057. Stack (30)
题目地址:http://pat.zju.edu.cn/contests/pat-a-practise/1057 用树状数组和二分搜索解决,对于这种对时间复杂度要求高的题目,用C的输入输出显然更好 #i ...
- spring boot配置写法
转自:http://blog.csdn.net/mickjoust/article/details/51646658 每日金句 你要搞清楚自己人生的剧本:不是你父母的续集,不是你子女的前传,更不是你朋 ...
- textLayout_1.0.0.595.swz
使用ai制作的矢量素材,导出到flash里面.生成swf时.有的时候会多一个textLayout_1.0.0.595.swz的文件. 这会导致导出的swf无法加载使用.会显示不出来. 解决办法是: 检 ...
- Android 开发第三天
今天学习的内容
- 使用CocoaPods遇到的几个坑,记录一下
最近使用pod的时候升级到1.0.0版本后遇到一些坑,整理一下 首先是CocoaPods报错:The dependency `` is not used in any concrete target ...