zoukankan      html  css  js  c++  java
  • 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工具位于:系统盘符:WINDOWSMicrosoft.NETFrameworkv3.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

  • 相关阅读:
    HDU1720 A+B Coming
    HDU1390 ZOJ1383 Binary Numbers
    HDU1390 ZOJ1383 Binary Numbers
    HDU2504 又见GCD
    HDU2504 又见GCD
    HDU1335 POJ1546 UVA389 UVALive5306 ZOJ1334 Basically Speaking
    HDU1335 POJ1546 UVA389 UVALive5306 ZOJ1334 Basically Speaking
    HDU1020 ZOJ2478 Encoding
    HDU1020 ZOJ2478 Encoding
    HDU2097 Sky数
  • 原文地址:https://www.cnblogs.com/zwb7926/p/3277165.html
Copyright © 2011-2022 走看看