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


    本节,将介绍如何手动构造复杂类型(ComplexType)以及复杂类型的简单操作。

    通常,复杂类型是指那些由几个简单的类型组合而成的类型。比如:一张Customer表,其中有FristNameLastName字段,那么对应的Customer实体类将会有FristNameLastName这两个属性。当我们想把FirstNameLastName合成一个名为CustomerName属性时,此时,如果要在EF中实现这个目的,那么我们就需要用到复杂类型。

    目前,由于EF不能显示支持复杂类型,所以我们无法在VS里的可视化设计器里面来设计我们需要的复杂类型。所以,我们需要手动修改实体模型,以便使其支持复杂类型的属性。修改的主要步骤有以下几步:

    l         产生实体模型

    l         修改CSDL文件

    l         修改msl文件

    l         重新生成模型实体类

    在后续的介绍,我使用数据库使用的是NorthWind,并针对Customer表对应的实体类来增加复杂属性Address,其中复杂属性AddressAddress,City,Region,CountryPostalCode这个几个组合而成。

    下面,介绍具体的操作步骤:

    第一步:产生实体模型

    实体模型的产生我们可以直接通过在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,CountryPostalCode属性定义,然后添加一个名为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.edmxNorthwindEnites.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

     
         本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
    原文链接:http://www.cnblogs.com/xray2005/archive/2009/06/01/1493661.html
  • 相关阅读:
    Node.js获得SQL Server驱动及更好的Windows工具
    二进制文件存取示例(VB&VBA)
    AmigaOS 4.1 Update 6 发布
    树形数据编号重排的通用存储过程
    谷歌升级云数据库:更多的储存及更快的读取
    nginx+keepalive主从 双机热备 + 自动切换解决方案
    sql导出mysql
    非UNICODE字段修改为UNICODE字段的可行性分析
    ipset 6.16.1 发布,网络设置工具
    Puppy Linux 5.4 "Precise" 发布
  • 原文地址:https://www.cnblogs.com/xwj517537691/p/3126790.html
Copyright © 2020-2023  润新知