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

那么如何手动构造复杂类型(ComplexType)以及复杂类型的简单动作呢?一般比如:一张用户表User,其中有两个字段FirstName和LastName,那么对应的User实体类将会FirstName和LastName两个属性。如果我们想把FirstName和LastName合成一个UserName属性时,并且想要在EF中实现这个想法,我们就需要用到复杂类型。

目前,由于EF不能显示支持复杂类型,所以我们也无法在VS中的可视化设计器中设计该复杂类型,所以我们只能暂时手动修改实体类型,以便可以支持复杂类型的属性。有如下几个步骤:

  1. 产生实体模型

  2. 修改CSDL文件

  3. 修改MSL文件

  4. 重新生成模型实体类

    在后续的介绍中,我会针对User表对应的实体类来增加复杂属性TelePhone,其中复杂属性TelePhone由Tel,NickName,Emal组成。

一、产生实体模型

实体模型我们可以使用VS自带的可视化设计器来实现。了解过EF的基础的朋友应该知道这个设计,具体步骤这里就复述了。我产生的实体模型UserInfoEntity.edmx。

二、修改CSDL文件

产生实体文件后,我们可以使用Notepad++打开实体模型,找到实体模型中关于CSDL定义的部分,然后找到实体类型名为Users的定义节,删除原来的Tel,NickName,Emal属性定义,增加一个名为TelePhone的属性节点。代码如下所示:

 <EntityType Name="Users">
<Key>
<PropertyRef Name="UsersID" />
</Key>
<Property Name="UserID" 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>

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

<ComplexType Name="CommonTelePhone">
<Property Name="Address" Type="String" MaxLength="60" Unicode="true" FixedLength="false" />
<Property Name="NickName" Type="String" MaxLength="30" Unicode="true" FixedLength="false" />
<Property Name="Region" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
<Property Name="Emal" Type="String" MaxLength="10" Unicode="true" FixedLength="false" />
<Property Name="Tel" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
</ComplexType>

到此,CSDL的修改部分已完毕。

三、MSL文件

找到MSL部分的定义,修改Users部分的影射定义。代码如下所示(请注意ComplexProperty 节):

 <EntitySetMapping Name="Users">
<EntityTypeMapping TypeName="IsTypeOf(NorthwindModel.Customers)">
<MappingFragment StoreEntitySet="Customers">
<ScalarProperty Name="UserID" 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="NickName" ColumnName="NickName" />
<ScalarProperty Name="Region" ColumnName="Region" />
<ScalarProperty Name="Emal" ColumnName="Emal" />
<ScalarProperty Name="Tel" ColumnName="Tel" />
</ComplexProperty>
<ScalarProperty Name="Phone" ColumnName="Phone" />
<ScalarProperty Name="Fax" ColumnName="Fax" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>

到此,MSL的修改部分已完毕。

四、重新产生实体类文件

我们可以使用EmdGen2工具来重新生成实体类.cs的文件。对于EmdGen2工具的使用方法就不在这里介绍了。具体可百度或者查看我之后关于EmdGen2工具的使用方法的博客。那么这里的具体操作就是如下所示。

将修改好的模型文件(edmx),拷贝到emdgen2.exe目录下,然后在命令行中输入:Emdgen2 /codegen cs NorthwindEnites.edmx。执行此命令后,会在当前文件夹中生成一个NorthwindEnites.cs的文件,也就是实体类的代码文件。接着将文件名改成:NorthwindEnites.Designer.cs,这一步骤主要是和edmx对应起来。

最后,将 NorthwindEnites.edmx 和NorthwindEnites.Designer.cs 文件添加到项目中。

至此,复合类型的修改完毕。

按照上述操作步骤,我们可以给Employess也增加一个Address 的复杂类型属性。

接下来,我们看看具体使用代码:

查询

public void TestAddress()
{
using (var db = new NorthwindModel.NorthwindEntities1())
{
Console.WriteLine("Get first users addresss :");
var cts = db.Customers.Take(5);
foreach (var c in cts)
{
Console.WriteLine("Address:{0},Tel:{1},NickName:{2},Emal:{3}",
c.Address.Address, c.Address.Tel, c.Address.NickName, c.Address.Emal);
}
Console.WriteLine("Get first Employess address:");
var emp = db.Customers.Take(5);
foreach (var c in emp)
{
Console.WriteLine("Address:{0},Tel:{1},NickName:{2},Emal:{3}",
c.Address.Address, c.Address.Tel, c.Address.NickName, c.Address.Emal);
}
}
}

添加

public void AddTest()
{
using (var db = new NorthwindModel.NorthwindEntities1())
{
var customer = new NorthwindModel.Customers
{
UserID = "340956",
CompanyName = "JinShan Company",
ContactName = "xray2017",
Address = new NorthwindModel.CommonAddress
{
Address = "WuHan,China",
NickName = "AiXiaoJun",
Tel = "15290896766",
Emal = "aixiaojun2012@163.com",
Region = "LiuHeng"
}
};
db.AddToCustomers(customer);
db.SaveChanges();
var cst = db.Customers.FirstOrDefault(c => c.CustomerID == "2009");
Assert.IsNotNull(cst);
Console.WriteLine("UserID:{0},CompanyName:{1},ContactName:{2},NickName:{3},Tel:{4}",
cst.UserID, cst.CompanyName, cst.ContactName, cst.Address.NickName, cst.Address.Tel);
}
}

有不对的地方请各位批评指正,互相学习!

EF学习笔记-2 EF之支持复杂类型的实现的更多相关文章

  1. EF学习笔记-1 EF增删改查

    首次接触Entity FrameWork,就感觉非常棒.它节省了我们以前写SQL语句的过程,同时也让我们更加的理解面向对象的编程思想.最近学习了EF的增删改查的过程,下面给大家分享使用EF对增删改查时 ...

  2. EF学习笔记(八):更新关联数据

    学习笔记主目录链接:ASP.NET MVC5 及 EF6 学习笔记 - (目录整理) 上一篇链接:EF学习笔记(七):读取关联数据 本篇原文链接:Updating Related Data 本篇主要考 ...

  3. EF学习笔记(十二):EF高级应用场景

    学习总目录:ASP.NET MVC5 及 EF6 学习笔记 - (目录整理) 上篇链接:EF学习笔记(十一):实施继承 本篇原文链接:Advanced Entity Framework Scenari ...

  4. EF学习笔记(十一):实施继承

    学习总目录:ASP.NET MVC5 及 EF6 学习笔记 - (目录整理) 上篇链接:EF学习笔记(十) 处理并发 本篇原文链接:Implementing Inheritance 面向对象的世界里, ...

  5. EF学习笔记(十) 处理并发

    总目录:ASP.NET MVC5 及 EF6 学习笔记 - (目录整理) 上一篇:EF学习笔记(九):异步处理和存储过程 本篇原文链接:Handling Concurrency Concurrency ...

  6. EF学习笔记(九):异步处理和存储过程

    总目录:ASP.NET MVC5 及 EF6 学习笔记 - (目录整理) 上一篇:EF学习笔记(八):更新关联数据 本篇原文:Async and Stored Procedures 为何要采用异步? ...

  7. C#学习笔记——面向对象、面向组件以及类型基础

    C#学习笔记——面向对象.面向组件以及类型基础 目录 一 面向对象与面向组件 二 基元类型与 new 操作 三 值类型与引用类型 四 类型转换 五 相等性与同一性 六 对象哈希码 一 面向对象与面向组 ...

  8. 一起学ASP.NET Core 2.0学习笔记(二): ef core2.0 及mysql provider 、Fluent API相关配置及迁移

    不得不说微软的技术迭代还是很快的,上了微软的船就得跟着她走下去,前文一起学ASP.NET Core 2.0学习笔记(一): CentOS下 .net core2 sdk nginx.superviso ...

  9. EF学习笔记(七):读取关联数据

    总目录:ASP.NET MVC5 及 EF6 学习笔记 - (目录整理) 本篇参考原文链接:Reading Related Data 本章主要讲述加载显示关联数据: 数据加载分为以下三种 Lazy l ...

随机推荐

  1. this高级应用 - 域隔离

    在js环境中,this有很多指向(window.dom.object等),巧妙的利用this,可以有效的防止变量或方法被外界污染,保证代码健壮性,实例如下. demo: <!DOCTYPE ht ...

  2. xml约束的概念

    1 xml 约束的概念 XML 指可扩展标记语言(EXtensible Markup Language) XML 是一种标记语言,很类似 HTML XML 的设计宗旨是传输数据,而非显示数据 XML ...

  3. python之Flask框架

    一.简单的Flask框架 1)flask简介 Flask 是一个 web 框架.也就是说 Flask 为你提供工具,库和技术来允许你构建一个 web 应用程序. 这个 wdb 应用程序可以使一些 we ...

  4. 46.UISearchBar的placeholder字体颜色和背景颜色

    1.改变searchbar的searchField属性 UITextField *searchField = [searchbar valueForKey:@"searchField&quo ...

  5. 2019.01.20 bzoj2238: Mst(kruskal+树链剖分)

    传送门 树链剖分菜题. 题意简述:给一个无向图,边有边权,每次询问删一条边(对后面的询问无影响)之后的最小生成树. 思路: 先跑一次kruskalkruskalkruskal并把跑出来的最小生成树给链 ...

  6. springboot深入学习(三)-----docker

    一.spring data思路 spring data使用统一的api来对各种数据库存储技术进行数据访问操作提供了支持,包括oracle.mysql.redis.mongoDB等等.主要是通过spri ...

  7. SQL语句之奇形怪状的冷门函数

    lag() over() ) OVER(ORDER BY C.column) FROM Table C; 第一条记录已经无法再取前一条记录,所以LAG()函数返回空. SQL为意思如下. LAG(C. ...

  8. HTML上传文件支持大文件上传,下载

    上传 1.修改配置文件web.config,在<system.webServer>下面加入 <security> <requestFiltering > <r ...

  9. event based xml parser (SAX) demo

    import java.io.ByteArrayInputStream; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SA ...

  10. wchar_t,char,string,wstring等的总结

    一.LPSTR LPCSTR LPTSTR LPCTSTR等 确定的类型: LPSTR = CHAR * = char * LPCSTR = const CHAR * = char * //c意为co ...