本节,将介绍如何手动构造复杂类型(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的属性,如下代码所示:

  1. <EntityType Name="Customers">
  2. <Key>
  3. <PropertyRef Name="CustomerID" />
  4. </Key>
  5. <Property Name="CustomerID" Type="String" Nullable="false" MaxLength="5" Unicode="true" FixedLength="true" />
  6. <Property Name="CompanyName" Type="String" Nullable="false" MaxLength="40" Unicode="true" FixedLength="false" />
  7. <Property Name="ContactName" Type="String" MaxLength="30" Unicode="true" FixedLength="false" />
  8. <Property Name="ContactTitle" Type="String" MaxLength="30" Unicode="true" FixedLength="false" />
  9. <Property Name="Address" Type="NorthwindModel.CommonAddress" Nullable="false"></Property>
  10. <Property Name="Phone" Type="String" MaxLength="24" Unicode="true" FixedLength="false" />
  11. <Property Name="Fax" Type="String" MaxLength="24" Unicode="true" FixedLength="false" />
  12. <NavigationProperty Name="Orders" Relationship="NorthwindModel.FK_Orders_Customers" FromRole="Customers" ToRole="Orders" />
  13. <NavigationProperty Name="CustomerDemographics" Relationship="NorthwindModel.CustomerCustomerDemo" FromRole="Customers" ToRole="CustomerDemographics" />
  14. </EntityType>

接着,需要添加一个名为CommonAddress复杂类型的定义,具体如下代码:

  1. <ComplexType Name="CommonAddress">
  2. <Property Name="Address" Type="String" MaxLength="60" Unicode="true" FixedLength="false" />
  3. <Property Name="City" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
  4. <Property Name="Region" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
  5. <Property Name="PostalCode" Type="String" MaxLength="10" Unicode="true" FixedLength="false" />
  6. <Property Name="Country" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
  7. </ComplexType>

至此,csdl部分修改完毕。

第三步,修改msl文件:
找到msl部分的定义,修改Customers部分的影射定义。具体代码如下(请注意ComplexProperty节):

  1. <EntitySetMapping Name="Customers">
  2. <EntityTypeMapping TypeName="IsTypeOf(NorthwindModel.Customers)">
  3. <MappingFragment StoreEntitySet="Customers">
  4. <ScalarProperty Name="CustomerID" ColumnName="CustomerID" />
  5. <ScalarProperty Name="CompanyName" ColumnName="CompanyName" />
  6. <ScalarProperty Name="ContactName" ColumnName="ContactName" />
  7. <ScalarProperty Name="ContactTitle" ColumnName="ContactTitle" />
  8. <ComplexProperty Name="Address" TypeName="NorthwindModel.CommonAddress">
  9. <ScalarProperty Name="Address" ColumnName="Address" />
  10. <ScalarProperty Name="City" ColumnName="City" />
  11. <ScalarProperty Name="Region" ColumnName="Region" />
  12. <ScalarProperty Name="PostalCode" ColumnName="PostalCode" />
  13. <ScalarProperty Name="Country" ColumnName="Country" />
  14. </ComplexProperty>
  15. <ScalarProperty Name="Phone" ColumnName="Phone" />
  16. <ScalarProperty Name="Fax" ColumnName="Fax" />
  17. </MappingFragment>
  18. </EntityTypeMapping>
  19. </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的复杂类型属性。
接下来,我们看看具体使用代码:

> 查询:

  1. public void TestAddress()
  2. {
  3. using (var db = new NorthwindModel.NorthwindEntities1())
  4. {
  5. Console.WriteLine("Get Five customer addresss :");
  6. var cts = db.Customers.Take();
  7. foreach (var c in cts)
  8. {
  9. Console.WriteLine("Address:{0},Country:{1},City:{2},PostalCode:{3}", c.Address.Address, c.Address.Country, c.Address.City, c.Address.PostalCode);
  10. }
  11. Console.WriteLine("Get Five Employess address:");
  12. var emp = db.Customers.Take();
  13. foreach (var c in emp)
  14. {
  15. Console.WriteLine("Address:{0},Country:{1},City:{2},PostalCode:{3}", c.Address.Address, c.Address.Country, c.Address.City, c.Address.PostalCode);
  16. }
  17. }
  18. }

>  添加:

  1. public void AddTest()
  2. {
  3. using (var db = new NorthwindModel.NorthwindEntities1())
  4. {
  5. var customer = new NorthwindModel.Customers
  6. {
  7. CustomerID = "",
  8. CompanyName = "Complex Company",
  9. ContactName = "xray2005",
  10. Address = new NorthwindModel.CommonAddress
  11. {
  12. Address = "SiChuan,China",
  13. City = "ChengDou",
  14. Country = "China",
  15. PostalCode = "",
  16. Region = "Chenghua"
  17. }
  18. };
  19. db.AddToCustomers(customer);
  20. db.SaveChanges();
  21. var cst = db.Customers.FirstOrDefault(c => c.CustomerID == "");
  22. Assert.IsNotNull(cst);
  23. Console.WriteLine("CustomerID:{0},CompanyName:{1},ContactName:{2},City:{3},Country:{4}", cst.CustomerID, cst.CompanyName, cst.ContactName, cst.Address.City, cst.Address.Country);
  24. }
  25. }

>  条件查询:

  1. public void QueryTest()
  2. {
  3. using (var db = new NorthwindModel.NorthwindEntities1())
  4. {
  5. var cst = db.Customers.FirstOrDefault(c => c.Address.City == "ChengDou");
  6. Assert.IsNotNull(cst);
  7. Console.WriteLine("CustomerID:{0},CompanyName:{1},ContactName:{2},City:{3},Country:{4}", cst.CustomerID, cst.CompanyName, cst.ContactName, cst.Address.City, cst.Address.Country);
  8. }
  9. }

最后,补充说明:
1, 在VS的可视化设计器里,不支持复杂类型,所以修改后无法再在可视化设计器里修改模型(edmx文件)。
2, 复杂类型不能单独存在,它必须和某一实体相关起来。
3, 复杂类型不能包含导航属性,如导航到实体或实体集。
4, 复杂类型具有内部结构但没有 Key(主键) 属性的数据类型

EF支持复杂类型的实现的更多相关文章

  1. Entity Framework 学习中级篇1—EF支持复杂类型的实现

    本节,将介绍如何手动构造复杂类型(ComplexType)以及复杂类型的简单操作. 通常,复杂类型是指那些由几个简单的类型组合而成的类型.比如:一张Customer表,其中有FristName和Las ...

  2. EF学习笔记-2 EF之支持复杂类型的实现

    使用过.NET的小伙伴们知道,在我们的实体模型中,除了一些简单模型外,还有一些复杂类型,如几个简单的类型组合而成的类型:而EF除了在实现基本的增删改查之外,也支持复杂类型的实现. 那么如何手动构造复杂 ...

  3. 实体类的枚举属性--原来支持枚举类型这么简单,没有EF5.0也可以

    通常,我们都是在业务层和界面层使用枚举类型,这能够为我们编程带来便利,但在数据访问层,不使用枚举类型,因为很多数据库都不支持,比如我们现在用的SqlServer2008就不支持枚举类型的列,用的时候也 ...

  4. EF里Guid类型数据的自增长、时间戳和复杂类型的用法

    通过前两章Lodging和Destination类的演示,大家肯定基本了解Code First是怎么玩的了,本章继续演示一些很实用的东西.文章的开头提示下:提供的demo为了后面演示效果,前面代码有些 ...

  5. 让Xcode的控制台支持LLDB类型的打印

    这个技巧个人认为非常有用 当Xcode在断点调试的时候,在控制台中输入 po self.view.frame 类似这样的命令会挂掉,不信可以亲自去试试(Xcode7 以后支持LLDB类型的打印) 那么 ...

  6. HttpWebRequest.AddRange 支持long类型

    很久很久以前,在哪个FAT32格式还流行的年代,文件大小普遍还没超过4G的年代,.Net已经出来了. 而那时候.Net实现的HTTP断点续传协议,还没预料到如此普及(我猜的).那时候的HttpWebR ...

  7. python操作Redis安装、支持存储类型、普通连接、连接池

    一.python操作redis安装和支持存储类型 安装redis模块 pip3 install redis 二.Python操作Redis之普通连接 redis-py提供两个类Redis和Strict ...

  8. 游戏开发中IIS常见支持MIME类型文件解析

    游戏开发中IIS常见支持MIME类型文件解析 .apkapplication/vnd.android .ipaapplication/vnd.iphone .csbapplication/octet- ...

  9. json序列化时定制支持datetime类型,和到中文让他保留中文形式

    json序列化时,可以处理的数据类型有哪些?如何定制支持datetime类型 自定义时间序列化转换器 import json from json import JSONEncoder from dat ...

随机推荐

  1. 局域网内Linux服务器时间同步

    局域网内Linux服务器时间同步   1.将一台能够上网的服务器作为时间服务器:  # /usr/bin/rdate -s time-b.timefreq.bldrdoc.gov //将时间服务器与互 ...

  2. SAP一句话入门 .

    SD是Sales and Distribution的简称.在SAP系统中,销售与分销模块处在供应链下游,关注从客户订单到向客户收款的全过程. SD模块中的Sales好理解,而Distribution却 ...

  3. javascript中的function对象

    function对象都是Function的实例: > Object.getOwnPropertyNames(Function) [ 'length', 'name', 'arguments', ...

  4. iOS 开发 NSLog调试小技巧

    NSLog其实是一个非常损耗性能的东西,当你在开发了很长时间的一个项目中,想必为了方便调试,里面会有很多的NSLog输出,为了优化性能,同时又方便调试,可以在pch中定义一个宏,既可以替换原有的NSL ...

  5. iOS不勾选设置,实现某个界面强制横屏

    1.在不勾选横屏的前提下,实现某一个界面横屏显示,比如播放视频.图表显示等. 2.只能Present跳转,Push会无效. 3.实现代码 在需要横屏的VC里,添加如下代码 #pragma mark 强 ...

  6. PAT 1057. Stack (30)

    题目地址:http://pat.zju.edu.cn/contests/pat-a-practise/1057 用树状数组和二分搜索解决,对于这种对时间复杂度要求高的题目,用C的输入输出显然更好 #i ...

  7. spring boot配置写法

    转自:http://blog.csdn.net/mickjoust/article/details/51646658 每日金句 你要搞清楚自己人生的剧本:不是你父母的续集,不是你子女的前传,更不是你朋 ...

  8. textLayout_1.0.0.595.swz

    使用ai制作的矢量素材,导出到flash里面.生成swf时.有的时候会多一个textLayout_1.0.0.595.swz的文件. 这会导致导出的swf无法加载使用.会显示不出来. 解决办法是: 检 ...

  9. Android 开发第三天

    今天学习的内容

  10. 使用CocoaPods遇到的几个坑,记录一下

    最近使用pod的时候升级到1.0.0版本后遇到一些坑,整理一下 首先是CocoaPods报错:The dependency `` is not used in any concrete target ...