2016-01-21 53 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