实体框架一对一关系映射在代码中展平

时间:2011-06-24 17:36:46

标签: entity-framework entity-framework-4.1

我有一个像这样的表结构。

Address:
AddressId int not null primary key identity
...more columns

AddressContinental:
AddressId int not null primary key identity foreign key to pk of Address
County
State

AddressInternational:
AddressId int not null primary key identity foreign key to pk of Address
ProvinceRegion

我无法控制架构,这就是它的方式。

现在,我想要做的是拥有一个Address对象。

public class Address
{
    public int AddressId { get; set; }
    public County County { get; set; }
    public State State { get; set }
    public ProvinceRegion { get; set; }
}

我希望EF将其作为单个实体从数据库中取出。保存时,我想保存单个实体并让EF知道将它拆分为三个表。

我如何在EF 4.1 Code First中映射它?

我一直在四处寻找,但还没有找到符合我要求的任何东西。

更新

地址记录将在Address中有一条记录,AddressContinentalAddressInternational中有一条记录,但不会同时记录。

2 个答案:

答案 0 :(得分:2)

以下是我将使用的Fluent API。

mb.Entity<Address>()
  .Map(m =>
  {
    m.Properties(p => new
    {
      p.AddressId
    });
    m.ToTable("Address");
  });

mb.Entity<Address>()
  .Map(m =>
  {
    m.Properties(p => new
    {
      p.AddressId,
      p.County,
      p.State
    });
    m.ToTable("AddressContinental");
  });

mb.Entity<Address>()
  .Map(m =>
  {
     m.Properties(p => new
     {
       p.AddressId,
       p.ProvinceRegion
     });
     m.ToTable("AddressInternational");
  });

答案 1 :(得分:1)

  

地址记录将有记录   在地址和其中一个   地址洲际或   AddressInternational,但不是两者。

此要求使您无​​法实现第一项要求。 @OpticalDelusion向您展示了如何映射实体拆分的方法,但它仅在需要所有部件时才有效。 EF无法有条件地执行此操作。此外,如果您尝试保存新的拆分实体,它将始终在所有3个表中创建新记录。

你需要的不是扁平物体,而是TPT(每种类型的表格)继承你将拥有:

public abstract class Address
{
    public int Id { get; set; }
    public string Name { get; set; }

}

public class AddressContinental : Address
{
    public string Country { get; set; }
    public string State { get; set; }
}

public class AddressInternational : Address
{
    public string ProvinceRegion { get; set; }
}

public class Context : DbContext
{
    public DbSet<Address> Addresses { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<AddressContinental>().ToTable("AddressContinental");
        modelBuilder.Entity<AddressInternational>().ToTable("AddressInternational");
    }
}

}