zoukankan      html  css  js  c++  java
  • Entity Framework 4.1 之四:复杂类型

    原文名称:Entity Framework 4.1: Complex Types (4)

    原文地址:http://vincentlauzon.wordpress.com/2011/04/13/entity-framework-4-1-complex-types-4/

    默认情况下,EF4.1 将类映射到表,这是约定,但是有时候,我们需要模型比表的粒度更细一些。

    地址是一个典型的例子,看一下下面的客户类。

    publicclass Client
    {
    publicint ClientID { get; set; }
    [Required]
    [StringLength(
    32, MinimumLength=2)]
    publicstring ClientName { get; set; }
    public Address ResidentialAddress { get; set; }
    public Address DeliveryAddress { get; set; }
    }

    publicclass Address
    {
    [Required]
    publicint StreetNumber { get; set; }
    [Required]
    [StringLength(
    32, MinimumLength=2)]
    publicstring StreetName { get; set; }
    }

    我们不希望其中的两个地址属性都映射到地址表中的记录,而是让 EF4.1 都映射到一张表中,将地址展开,如何做到呢?可以通过复杂类型。

    像我们前面看到的,我们总是通过标签或者模型构建器来覆盖默认约定。我提到过,当我们丰富业务模型的时候,例如必填项,我建议使用属性。现在我考虑将类中的复杂属性映射到表中的字段,所以这里不是用标签,而是使用模型构建器。

    protectedoverridevoid OnModelCreating(DbModelBuilder modelBuilder)
    {
    base.OnModelCreating(modelBuilder);

    modelBuilder.Entity
    <Client>().Property(x => x.ClientID)
    .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
    modelBuilder.ComplexType
    <Address>();
    modelBuilder.Entity
    <Client>().Property(i => i.ResidentialAddress.StreetNumber).HasColumnName("ResStreetNumber");
    modelBuilder.Entity
    <Client>().Property(i => i.ResidentialAddress.StreetName).HasColumnName("ResStreetName");
    modelBuilder.Entity
    <Client>().Property(i => i.DeliveryAddress.StreetNumber).HasColumnName("DelStreetNumber");
    modelBuilder.Entity
    <Client>().Property(i => i.DeliveryAddress.StreetName).HasColumnName("DelStreetName");

    }

    首先,我指定 client-id 作为自动增长的标识列。然后,指定 Address 是复杂类型。如果愿意的话,也可以将 [ComplexType] 标签加到类上来说明。然后,使用 Lambda 表达式将每一个子属性映射到列上,这将会生成如下的表。

    现在,可以使用模型了。

    using (var context1 =new MyDomainContext())
    {
    var client
    =new Client
    {
    ClientName
    ="Joe",
    ResidentialAddress
    =new Address
    {
    StreetNumber
    =15,
    StreetName
    ="Oxford"
    },
    DeliveryAddress
    =new Address
    {
    StreetNumber
    =514,
    StreetName
    ="Nolif"
    }
    };
    context1.Clients.Add(client);

    context1.SaveChanges();
    }
    using (var context2 =new MyDomainContext())
    {
    var clients
    = from w in context2.Clients
    where w.ClientName =="Joe"
    select w;

    foreach (var client in clients)
    {
    Console.WriteLine(
    "client residential StreetNumber: "+ client.ResidentialAddress.StreetNumber);
    Console.WriteLine(
    "client residential StreetName: "+ client.ResidentialAddress.StreetName);
    Console.WriteLine(
    "client delivery StreetNumber: "+ client.DeliveryAddress.StreetNumber);
    Console.WriteLine(
    "client delivery StreetName: "+ client.DeliveryAddress.StreetName);
    }
    }

    对于复杂类型,最值得注意的是空的管理。即使复杂类型的所有属性都是可空的,你也不能将整个复杂类型的对象设为 null, 例如,在这种情况下,即使街道的名称和街道的号码不是必填的,也不能有一个住宅的地址为 null,需要创建一个所有属性都是 null 的地址对象来表示。同样的道理,当你获取一个实体的时候,即使所有的属性都是 null ,EF4.1 也将会创建一个复杂类型的对象。

  • 相关阅读:
    LeetCode Best Time to Buy and Sell Stock
    LeetCode Scramble String
    LeetCode Search in Rotated Sorted Array II
    LeetCode Gas Station
    LeetCode Insertion Sort List
    LeetCode Maximal Rectangle
    Oracle procedure
    浏览器下载代码
    Shell check IP
    KVM- 存储池配置
  • 原文地址:https://www.cnblogs.com/haogj/p/2040093.html
Copyright © 2011-2022 走看看