本节,将介绍如何手动构造复杂类型(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(主键) 属性的数据类型

最新文章

  1. 子DIV设置margin-top影响父DIV位置的解决办法
  2. [实践] Android5.1.1源码 - 让某个APP以解释执行模式运行
  3. 做一个阅读管理APP
  4. [Android Tips] 2. Disable recent apps dialog on long press home button
  5. IT公司100题-tencent-打印所有高度为2的路径
  6. [ACM_几何] UVA 11300 Spreading the Wealth [分金币 左右给 最终相等 方程组 中位数]
  7. 29.调整数组顺序使奇数位于偶数前面[ReOrderArray]
  8. NOJ 1072 The longest same color grid(尺取)
  9. MBProgressHUD.h file not found
  10. 3 Ways to Preload Images with CSS, JavaScript, or Ajax---reference
  11. 10、第十节课jq420151012
  12. java.lang.String 类源码解读
  13. MyBatis Generator报错:Cannot instantiate object of type
  14. AI 隐马尔科夫模型
  15. windows系统上搭建redis集群哨兵及主从复制
  16. 学习笔记之1001 Inventions That Changed the World
  17. JS 解析JSON实现导序
  18. SpringBoot下的Job定时任务
  19. (转)MySQL 常用数据存储引擎区别
  20. js继承的实现(es5)

热门文章

  1. .NET Compact Framework Data Provider for SQL Server CE
  2. static与线程安全 -摘自网络
  3. VPN两点注意事项
  4. 【原】用PHP搭建基于swoole扩展的socket服务(附PHP扩展的安装步骤及Linux/shell在线手册)
  5. 拍照返回的bitmap太小
  6. Add-VMNetworkAdapterAcl(添加访问控制列表)
  7. Tomcat 优化
  8. MySQL B+树索引和哈希索引的区别
  9. 【转】针对iOS VS. Android开发游戏的优劣&mdash;&mdash;2013-08-25 17
  10. shell脚本结构示例1