EntityFramework - 每种类型的表(TPT)与CodeFirst

时间:2016-01-21 13:30:46

标签: c# .net entity-framework

我有以下实体,我坚持使用EntityFramework 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
}

基本上,用户可以属于零个或一个红色组,以及多个绿色组。每个组都有一组属于它的用户。

我正在尝试使用TPT使用CodeFirst设置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映射以允许每个类型的层次结构?

1 个答案:

答案 0 :(得分:0)

我创建了一个没有映射的上下文,但配置更简单,一切似乎都创建好了:

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

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

我注意到您已定义[User] .HasOptional(t => t.RedGroup),但User上的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