2016-01-21 52 views
1

映射關係我有以下實體其中,我使用的EntityFramework CodeFirst堅持:的EntityFramework - 每個類型表(TPT)繼承和與CodeFirst

public class User { 

    RedGroup RedGroup { get; protected set; } 
    virtual ICollection<GreenGroup> GreenGroups { get; } 

    int Id { get; protected set; } 
    int? RedGroupId { get; protected set; } 
} 

public abstract class Group { 

    int Id { get; protected set; } 
    virtual ICollection<User> Users { get; protected set; } 
} 

public class RedGroup : Group { 
    // Other properties 
} 

public class GreenGroup : Group { 
    // Other properties 
} 

本質上,用戶可以屬於零個或一個紅基團,和不止一個綠色組織。每個組都有一組屬於它的用戶。

我想使用CodeFirst與TPT設置EF,並且在排序映射時遇到問題。目前,我在OnModelCreating如下:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    modelBuilder.Configurations.Add(new RedGroupMap()); 
    modelBuilder.Configurations.Add(new GreenGroupMap()); 
    modelBuilder.Configurations.Add(new UserMap()); 
} 

這些是映射類:

public abstract class GroupMap<T> : EntityTypeConfiguration<T> 
    where T : Group { 

    public GroupMap() { 

     this.ToTable("Groups"); 

     this.HasKey(t => t.Id); 
     this.Property(t => t.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity).HasColumnName("Id"); 

     // Also has other non-relationship mappings 
    } 

} 

public class RedGroupMap() : GroupMap<RedGroup> { 

    public RedGroupMap() { 

     this.ToTable("RedGroups"); 

     // Also has other non-relationship mappings 
    } 
} 

public class GreenGroupMap() : GroupMap<GreenGroup> { 

    public GreenGroupMap() { 

     this.ToTable("GreenGroups"); 

     this.HasMany(c => c.Users) 
      .WithMany(p => p.GreenGroups) 
      .Map(m => 
      { 
       m.MapLeftKey("GreenGroupId"); 
       m.MapRightKey("UserId"); 
       m.ToTable("Users_GreenGroups"); 
      }); 

     // Also has other non-relationship mappings 
    } 
} 

public class UserMap() : EntityTypeConfiguration<User> { 

    this.ToTable("Users"); 
    this.HasKey(t => t.Id); 
    this.Property(t => t.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity).HasColumnName("Id"); 

    this.HasOptional(t => t.RedGroup) 
      .WithMany(t => t.Users) 
      .Map(x => x.MapKey("RedGroupId")) 
      .WillCascadeOnDelete(false); 
} 

我得到以下運行時錯誤:

Users: FromRole: NavigationProperty 'Users' is not valid. Type 'RedGroup' of FromRole 'User_RedGroup_Target' in AssociationType 'User_RedGroup' must exactly match with the type 'GreenGroup' on which this NavigationProperty is declared on.

怕我對於如何設置這一點,他非常沮喪。

如何設置EntityFramework映射以允許Table per Type層次結構?

回答

0

我創建了一個上下文沒有你的映射,但有更簡單的配置,一切都似乎創造OK:

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

    modelBuilder.Entity<Group>().ToTable("Groups"); 
    modelBuilder.Entity<RedGroup>().ToTable("RedGroups"); 
    modelBuilder.Entity<GreenGroup>().ToTable("GreenGroups"); 
} 

我注意到您已經定義[用戶] .HasOptional(t => t.RedGroup),但RedGroupId場在用戶被定義爲int而不是int? - 也許這是相關的?

public class User { 
    int? RedGroupId { get; protected set; } // int -> int? 
    RedGroup RedGroup { get; protected set; } // virtual missing, but shouldn't matter 

    // Other properties 
} 

如果需要RedGroup,請嘗試使用.HasRequired來代替。

+0

從錯誤消息我認爲關聯映射是什麼導致的問題,所以如果你的簡化版本中缺少映射,那麼我猜這個問題不會出現。 int?只是一個錯字。 – Graham