实体框架-EF 4.1对多对多关系的映射继承



混乱局面
我有一种情况,我有两个实体,其中1个从另一个继承,需要映射到两个单独的表,但代码的使用应该围绕这两个实体的基础。

详细信息

public class Team
{
  public virtual int Id { get; set; }
  public virtual ICollection<Employee> Members { get; set; }
}
public class Employee
{
  public virtual int Id { get; set; }
  public virtual string Name { get; set; }
  public virtual ICollection<Team> Teams { get; set; }
}
public class EmployeeInfo : Employee
{
  public virtual int Id { get; set; }
  public virtual decimal Amount { get; set; }
}

我们有一个现有的数据库模式,其中Employee和EmployeeInfo是独立的表,Employe_Info_Id和Employme_Id之间有一个FK。

在我们的系统中,"经理"将使用一组私人信息(比上面列出的更多的属性)(如工资)将员工的添加到系统中,并将他们添加到团队中。系统的其他区域将使用Team或Employee对象进行各种其他操作。如果可以完成映射,我们希望代码非常简单。

当经理创建新员工时,我们希望代码看起来像这样:

public void Foo(string name, decimal pay)
{
  // create the employee
  var employee = new EmployeeInfo();
  employee.Name = name;
  employee.Pay = pay;
  // add him/her to the team
  _team.Employees.Add(employee);   // the idea being that consumers of the Team entity would not get the separate employee info properties
  // save the context
  _context.SaveChanges();
}

最终结果是,EmployeeInfo属性输入EmployeeInfo表,基础Employee数据输入Employme表,并通过关联表TeamEmployees添加到团队。

到目前为止,我正在尝试当前的映射,但在向团队添加员工时,我得到了一个名为"Discriminator"的无效列。

public class TeamConfiguration : EntityTypeConfiguration<Team>
{
    public TeamConfiguration()
    {
        ToTable("Team");
        HasKey(t => t.Id);
        HasMany(t => t.Members).WithMany(m => m.Teams)
            .Map(m =>
                     {
                         m.MapLeftKey("Team_Id");
                         m.MapRightKey("Employee_Id");
                         m.ToTable("TeamEmployees");
                     });
    }
}
public class EmployeeConfiguration : EntityTypeConfiguration<Employee>
{
    public EmployeeConfiguration()
    {
        ToTable("Employee");
        ToTable("EmployeeInfo");
        HasKey(t => t.Id);
        Property(p => p.Name);
        HasMany(m => m.Teams)
            .WithMany(t => t.Members)
            .Map(m =>
                     {
                         m.MapLeftKey("Employee_Id");
                         m.MapRightKey("Team_Id");
                         m.ToTable("TeamEmployees");
                     });
    }
}

此外,如果我去掉团队和员工之间的多对多,我会在employee_Id到EmployeeInfo_Id上得到一个FK异常。

谢谢,JR.

Discriminator是在使用Table Per Hierarchy方法时添加到表中的列
我想你要找的是"每种类型的表格(TPT)"。按如下方式装饰您的EmployeeInfo类:

[Table("EmployeeInfo")]
public class EmployeeInfo : Employee 

或者在您的OnModelCreating活动中添加以下内容:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
 ...
 modelBuilder.Entity<EmployeeInfo>().ToTable("EmployeeInfo");
 ...
}  

或者,创建以下类,并像OnModelCreating方法中的modelBuilder.Configurations.Add(new EmployeeInfoConfiguration());一样使用它:

public class EmployeeInfoConfiguration : EntityTypeConfiguration<EmployeeInfo>
{
    public EmployeeInfoConfiguration()
    {
        ToTable("EmployeeInfo");
    }
}

这将导致EF创建具有必要约束的EmployeeInfo表。

此外,最好在对象的构造函数中初始化集合,以防止出现null异常。例如在Team类中:

public Team()
{
    this.Employees = new HashSet<Employee>();
}  

我准确地复制了你的代码,并更改了以下部分:

public class Team
{
    public Team()
    {
        this.Members = new HashSet<Employee>();
    }
    public virtual int Id { get; set; }
    public virtual ICollection<Employee> Members { get; set; }
}
public class Employee
{
    public Employee()
    {
     this.Teams = new HashSet<Team>();
    }
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual ICollection<Team> Teams { get; set; }
}
[Table("EmployeeInfo")]
public class EmployeeInfo : Employee
{
    public virtual int Id { get; set; }
    public virtual decimal Amount { get; set; }
}  

在DbContext中,没有更改:

public partial class TestEntities : DbContext
{
    public DbSet<Employee> Employees { get; set; }
    public DbSet<EmployeeInfo> Employee_Info { get; set; }
    public DbSet<Team> Teams { get; set; }
}  

以及您的工作Foo方法:

public static void Foo(string name, decimal pay)
{
    var _team = new Team();
    var context = new TestEntities();
    context.Teams.Add(_team);
    // create the employee
    var employee = new EmployeeInfo();
    employee.Name = name;
    employee.Amount = pay;
    context.Employees.Add(employee);
    context.SaveChanges();
    // add him/her to the team
    _team.Members.Add(employee);   
    // save the context
    context.SaveChanges();
}  

最后,从EmployeeConfiguration中删除ToTable("EmployeeInfo");部分,因为您已经在模式创建事件中正确地提到了这一点。

有关"按类型表"方法的更多信息,请查看这篇很棒的文章。

相关内容

  • 没有找到相关文章

最新更新