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

时间:2022-09-17 10:37:17

本节,将介绍如何手动构造复杂类型(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工具的连接。

示例代码  EdmGen2

Entity Framework 学习中级篇1—EF支持复杂类型的实现的更多相关文章

  1. Entity Framework 学习中级篇3—存储过程&lpar;中&rpar;

    目前,EF对存储过程的支持并不完善.存在以下问题: l         EF不支持存储过程返回多表联合查询的结果集. l         EF仅支持返回返回某个表的全部字段,以便转换成对应的实体.无法 ...

  2. Entity Framework 学习中级篇2—存储过程&lpar;上&rpar;

    目前,EF对存储过程的支持并不完善.存在以下问题: l         EF不支持存储过程返回多表联合查询的结果集. l         EF仅支持返回返回某个表的全部字段,以便转换成对应的实体.无法 ...

  3. Entity Framework 学习中级篇4—存储过程&lpar;下&rpar;

    在EF中,各个实体的插入.更新和删除也都通过使用存储过程来完成,以便提高点性能.这个类似于数据集.其步骤是:先定义存储过程,然后在VS的可视化设计器,设置存储过程映射即可. 下面,以为Supplier ...

  4. Entity Framework学习初级篇2

    Entity Framework 学习初级篇2--ObjectContext.ObjectQuery.ObjectStateEntry.ObjectStateManager类的介绍 本节,简单的介绍E ...

  5. Entity Framework 学习初级篇1--EF基本概况

    转自:http://www.cnblogs.com/Tally/archive/2012/09/14/2685011.html 最近在学习研究微软的EF,通过这时间的学习研究,感觉这个EF目前来说还不 ...

  6. Entity Framework学习初级篇1--EF基本概况《转》

    最近在学习研究微软的EF,通过这时间的学习研究,感觉这个EF目前来说还不是很完善,半成品.不过,据说在.Net4.0中,微软将推荐使用此框架,并会有所改善.而且,现在基本上所有数据库均提供了对EF的支 ...

  7. Entity Framework 学习初级篇--基本操作:增加、更新、删除、事务&lpar;转&rpar;

    摘自:http://www.cnblogs.com/xray2005/archive/2009/05/17/1458568.html 本节,直接写通过代码来学习.这些基本操作都比较简单,与这些基本操作 ...

  8. Entity Framework 学习初级篇7--基本操作:增加、更新、删除、事务

    本节,直接写通过代码来学习.这些基本操作都比较简单,与这些基本操作相关的内容在之前的1至6节基本介绍完毕. l           增加: 方法1:使用AddToXXX(xxx)方法:实例代码如下: ...

  9. Entity Framework 学习高级篇1—改善EF代码的方法(上)

    本节,我们将介绍一些改善EF代码的相关方法,如NoTracking,GetObjectByKey, Include等. l         MergeOption.NoTracking 当我们只需要读 ...

随机推荐

  1. 如何获取网页上的LOGO

    一般公司网页上的图片都会禁止右键另存为,用截图工具接下来的图会带背景色,PS成背景透明有点费时间. 用Google Chrome 或Firefox 打开目标网页,右键点击审查元素,将鼠标放在图片上,一 ...

  2. 前端bower使用

    Bower是一个客户端技术的软件包管理器,是由twitter推出的.它可用于搜索.安装和卸载如JavaScript.HTML.CSS之类的网络资源.其他一些建立在Bower基础之上的开发工具,如Yeo ...

  3. Linux C 文件与目录4 将缓冲区数据写入磁盘

    将缓冲区数据写入磁盘 所谓缓冲区,是Linux系统对文件的一种处理方式.在对文件进行写操作时,并没有立即把数据写入到磁盘,而是把数据写入到缓冲区.如果需要把数据立即写入到磁盘,可以使用sync函数.用 ...

  4. 图像处理界的标准图像Lena背后的故事

    今天晚上实验室的哥们问到我:“蒋志强,你知道咱们数字图像处理界标准图像Lena吗?” “当然知道啊,不就是那个512×512的美丽姐姐的标准图像么?”我不以为然的回答: “那幅图像事实上不是原始图像? ...

  5. mysql统计表的大小

    如下是sql语句: SELECT TABLE_NAME as name,DATA_LENGTH+INDEX_LENGTH as len,TABLE_ROWS as rows FROM informat ...

  6. 如果你要查看文件的每个部分是谁修改的&comma; 那么 git blame 就是不二选择

    原文: http://gitbook.liuhui998.com/5_5.html 如果你要查看文件的每个部分是谁修改的, 那么 git blame 就是不二选择. 只要运行'git blame [f ...

  7. golang xml和json的解析与生成

    golang中解析xml时我们通常会创建与之对应的结构体,一层层嵌套,完成复杂的xml解析. package main; import ( "encoding/xml" &quot ...

  8. hbase使用MapReduce操作4(实现将 HDFS 中的数据写入到 HBase 表中)

    实现将 HDFS 中的数据写入到 HBase 表中 Runner类 package com.yjsj.hbase_mr2; import com.yjsj.hbase_mr2.ReadFruitFro ...

  9. 评论抓取:Python爬取微信在APPStore上的评论内容及星级

    #完整程序如下: import requests import re def getHTMLText(url): try: r = requests.get(url) r.raise_for_stat ...

  10. cas忽略地址配置

    项目中需要忽略部分地址不需要cas验证,网上资料不多,结合cas源码,找到了配置方法:web.xml中增加ignorePattern配置.实际上是通过正则表达式来匹配. <filter> ...