Entity Framework 4 - Code First not storing inherited table separate from base table
With EF Code First CTP 4 I've created a simple project. This project consists of 2 classes, one inherited from other.
I wish to store the data in separate tables, but the default of EF 4 is to map/store these two entities in the same table.
With .ToTable()
, I can change this behavior, but with this I have a side effect: when I persist a Inherited object, EF doesn't persist the common values (ex. Id) on the base class.
I'm sure I'm leaving to s开发者_C百科et some information in the mapping but do not know which.
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; }
}
Don't really know about CTP4, but in CTP5 this can be done using .Map(x=>x.ToTable("TableName"))
here is example of what you want:
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: I used SqlCe 4.0 as database engine. This fails to start, if Mammal
class has only Id
and no other properties (Don't know why). So I added Name
property base class. I'm not sure weather it is problem in CTP4, SqlCe 4.0, or I just don't know something.
Hope this helps.
精彩评论