• EF学习笔记-2 EF之支持复杂类型的实现


    使用过.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);
                }
            }
    

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

  • 相关阅读:
    Windows 配置 allure report 环境
    ruby 异常处理 begin rescue end
    ruby 安装 mysql2 命令
    Linux 新建文件/文件夹,删除文件文件夹,查找文件 打开文件
    Ubuntu 共享 转载
    单元测试框架 unittest 的运行方法if __name__ == '__main__': unittest.main()
    Python 字典和json的本质区别(个人理解)

    接口自动化大致流程。
    iOS开发UI篇—CAlayer(自定义layer)
  • 原文地址:https://www.cnblogs.com/aixiaojun/p/8993194.html
Copyright © 2020-2023  润新知