实体框架4 - 代码优先不存储与基表分开的继承表

时间:2010-07-28 19:58:21

标签: entity-framework entity code-first

使用EF Code First CTP 4,我创建了一个简单的项目。该项目由2个类组成,其中一个继承自其他类。

我希望将数据存储在单独的表中,但EF 4的默认值是将这两个实体映射/存储在同一个表中。

使用.ToTable(),我可以改变这种行为,但是这有一个副作用:当我持久化一个Inherited对象时,EF不会在基类上保留公共值(例如Id)。

我确定我要离开在映射中设置一些信息,但不知道哪个。

static void Main(string[] args)
{
    Database.SetInitializer<ZooContext>(new RecreateDatabaseIfModelChanges<ZooContext>());
    using (ZooContext ctx = new ZooContext())
    {
        Mammal mam = new Mammal() ;
        mam.NumberOfLegs = 4;
        ctx.Animals.Add(mam);
        // ctx.Mammals.Add(mam)  as the same behavior
        ctx.SaveChanges();
    }
}


public class ZooContext : DbContext
{   
    public DbSet<Animal> Animals { get; set; }
    public DbSet<Mammal> Mammals { get; set; }

    protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Animal>().HasKey(p => p.Id).
                                    MapHierarchy().
                                    Case<Animal>(a => new { a.Id });
        modelBuilder.Entity<Animal>().HasKey(p => p.Id).
                                    MapHierarchy().
                                    Case<Mammal>(a => new { a.Id, a.NumberOfLegs }).ToTable("Mammals");

        base.OnModelCreating(modelBuilder);
    }
}

public class Animal
{
    public virtual int Id { get; set; }
}

public class Mammal : Animal
{
    public int NumberOfLegs { get; set; }
}

1 个答案:

答案 0 :(得分:1)

真的不知道CTP4,但在CTP5中可以使用.Map(x=>x.ToTable("TableName"))来完成这里你想要的例子:

public class Mammal
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class Animal : Mammal
{
    public int NumberOfLegs { get; set; }
}

public class ZooContext : DbContext
{
    public DbSet<Mammal> Mammals { get; set; }
    public DbSet<Animal> Animals { get; set; }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        builder.Entity<Mammal>()
            .Map<Animal>(x => x.ToTable("Animals"))
            .Map<Mammal>(x => x.ToTable("Mammals"));

        base.OnModelCreating(builder);
    }
} 

class Program
{
    static void Main()
    {
        DbDatabase.SetInitializer(new DropCreateDatabaseIfModelChanges<ZooContext>());

        using (var ents = new ZooContext())
        {
            ents.Mammals.Add(new Animal { Name = "First Mutant Animal", NumberOfLegs = 10 });
            ents.Mammals.Add(new Mammal { Name = "First Mammal" });
            ents.Mammals.Add(new Mammal { Name = "Second Mammal" });
            ents.SaveChanges();
        }
    }
}

PS:我使用SqlCe 4.0作为数据库引擎。如果Mammal类只有Id且没有其他属性(不知道原因),则无法启动。所以我添加了Name属性基类。我不确定天气是CTP4,SqlCe 4.0中的问题,还是我什么都不知道。

希望这有帮助。