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 ...
随机推荐
- CentOS下源码安装Apache2.4+PHP5.4+MySQL5.5
一.准备(把所有的源文件放在‘/home/yuanjun’目录下) apr http://mirror.bjtu.edu.cn/apache/apr/apr-1.4.6.tar.gz apr-util ...
- 问题-[DelphiXE2]编译程序体积大的问题
作者:cashfly 发布:2012-03-27 15:12 最近准备换Delphi高版本来写程序,以前一直用7.想体验一下新版本带来的便捷,首先有一个体积问题,看下文介绍. 首先,在IDE里可以直接 ...
- 问题-[Delphi]PixelFormat 图像颜色的数据格式
PixelFormat: (指定图像中每个像素的颜色数据的格式) Delphi 微软 ...
- Modules you should know in Python Libray
前两天被问到常用的python lib和module有哪些?最常用的那几个,其他的一下子竟然回答不上.想想也是,一般情况下,遇到一个问题,在网上一搜,顺着线索找到可用的例子,然后基本没有怎么深究.结果 ...
- C# Adomd Connection Analysis Service View Cube
首先需要先引用 C:\Program Files\Microsoft.NET\ADOMD.NET\100\Microsoft.AnalysisServices.AdomdClient.dll ...
- iOS 使用fir、 蒲公英 进行内部测试
fir 蒲公英需要去注册账号并认证,按提示即可完成. 测了公司账号.个人开发账号,2个都可以用,就是要在配置文件里加上测试者的udid. 步骤: 1.添加测试机的udid edit配置文件,添加刚刚加 ...
- android ORMlite的应用
ORMLite -轻量级的对象关系映射(ORM) 如果你需要在android中使用ORMLite 你需要进入官方网站http://ormlite.com/ 中下载 下载了这两个包以后,你还需要在对应的 ...
- python学习(4)
python(4)4.1 高阶函数:map/reduce map:实际上map也是一个函数,只不过他可以在参数里面包含别的函数.他有两种参数:第一种:函数(作用在后面要说的序列上),第二种:一个序列 ...
- WPF-21:WPF实现仿安卓的图案密码键盘(改进)
前面写了个简单的实现( http://blog.csdn.net/yysyangyangyangshan/article/details/9280439),不过效果不太好,各个点之间没有连接起来.这里 ...
- linux shell突然显示-bash-4.1#的解决方法
老沙昨天还登录这个linux服务器,并且命令行好好的,今天突然在linux shell中不显示路径了,显示为-bash-4.1#. 以下是老沙的解决方案 vim ~/.bash_profile 如果没 ...