2011-08-22 73 views
17

我有一个类层次结构,我想要使用Entity Framework 4.1 Code First在几个表中映射。这就像每个表格类型(TPT),但我也想要一个表达式列。我可以使用每种类型映射指定一个鉴别器列吗?

层次结构看起来类似:

public class Event 
{ 
    public Guid Id { get; set; } 
    public string Code { get; set; } // discriminator 
    public DateTime Date { get; set; } 
} 

public class Party : Event 
{ 
    public int AttendeeCount { get; set; } 
} 

public class BirthdayParty : Party 
{ 
    public int Age { get; set; } 
} 

public class WeddingParty : Party 
{ 
    public string Surname { get; set; } 
} 

这是一个非常弱的例子,但我希望这是有道理的。会有一个“活动”表,一个“派对”表和每种派对的桌子。然而,鉴别器栏(“Code”)对于每种事件都将具有已知值,例如生日派对的“BIRTH”或婚礼派对的“WEDDING”。

这个想法是,如果我查询给定日期的生日派对,EF会知道将Code = 'BIRTH'添加到我的查询中,而不是执行一堆UNION和JOIN来计算出它需要的行。

我我的最低级别类映射是这样的:

var bd = modelBuilder.Entity<BirthdayParty>(); 
bd.ToTable("BirthdayParties"); 
bd.Property(p => p.Age).HasColumnName("BirthdayAge"); 

我现在需要有某种方式来指定的鉴别值。我已经试过这样:

modelBuilder.Entity<Event>().Map<BirthdayParty>(cfg => 
    { 
     cfg.Requires("Code").HasValue("BIRTH"); 
    }); 

...但抱怨我没有指定调用Map里面的表名。所以,我想在ToTable呼叫迁入有:

var bd = modelBuilder.Entity<BirthdayParty>(); 
bd.Property(p => p.Age).HasColumnName("BirthdayAge"); 

modelBuilder.Entity<Event>().Map<BirthdayParty>(cfg => 
    { 
     cfg.Requires("Code").HasValue("BIRTH"); 
     cfg.ToTable("BirthdayParties"); 
    }); 

...现在它认为我想在“BirthdayParties”表,这是不正确的一个“代码”一栏。我已经告诉过它,“代码”列在“事件”表中。

这甚至可能吗?我是否可以将鉴别器列与每种类型映射结合使用?

回答

8

不幸的是,这不支持。鉴别器列只能用于TPH。 TPT根据映射表来区分实体类型,并且它总是产生可怕的查询。这可能是一个很好的功能,所以也许建议Data UserVoice将使它有一天实施。

更新

目前已经在用户语音的建议,这个名为“Discriminator column support in TPT inheritance”。

0

我在SaveChanges上做了一个覆盖来完成类似的事情。我只是简单地将一个属性添加到名为Descriminator的抽象类中,并在添加新内容时随时根据具体类名称进行设置。

public class MyContext : DbContext 
{   
    public override int SaveChanges() 
    { 
     foreach (var item in ChangeTracker.Entries().Where(x=>x.Entity is MyAbstractClass && x.State == EntityState.Added)) 
     { 
      ((MyAbstractClass)item.Entity).Descriminator = item.Entity.GetType().Name; 
     } 
     return base.SaveChanges(); 
    } 
} 
相关问题