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 也将会创建一个复杂类型的对象。

  • 相关阅读:
    Django 前戏
    SQL基本语句
    如何正确安装Mysql
    JQuery
    解疑答惑—解决脱离标准文档流(恶心的浮动)
    事件
    卷基于快照进行恢复
    centos7下Firewall使用详解
    基于镜像卷启动的虚机快照代码分析
    nova卸载volume源码分析
  • 原文地址:https://www.cnblogs.com/haogj/p/2040093.html
Copyright © 2011-2022 走看看