多对多自我参考

时间:2018-08-14 12:38:42

标签: c# asp.net-mvc-5 entity-framework-6 many-to-many data-annotations

一个用户可以管理许多公司。用户可以一次从多个公司列表中拥有一个活跃的公司。我该如何实现?

我当前的模型是:

public class User
{
    public int Id

    public virtual ICollection<Company> Companies { get; set; }

    public User()
    {
        this.Companies = new HashSet<Company>();
    }
}
public class Company
{
    public int Id

    public virtual ICollection<User> Users { get; set; }

    public User()
    {
        this.Users = new HashSet<User>();
    }
}

如果我添加另一个注释:

public class User
{
    public int CompanyId

    public virtual Company Company { get; set; }
}

此模型不会引用UserCompany表中的多对多表。

我该如何实现?还是针对这种情况有另一种方法?

enter image description here

现在,我正在考虑制作手动的多对多关系模型,并添加从自定义多对多关系引用的另一个ActiveCompany字段。这是好方法吗?

2 个答案:

答案 0 :(得分:0)

我很确定您可以通过使用流畅的api并在OnModelCreating中覆盖DbContext方法来做到这一点,但是我没有示例。

但是,您可能会发现为用户添加另一个属性会更容易

public int ActiveCompanyId { get; set; }

有很多变量,例如您是否使用延迟加载,有多少家公司/用户,您的数据访问方式是什么,这些可能决定您最好的整体方法。如果您的Companies属性通常或始终被填充,那么您可以创建一个仅get的未映射属性:

public class User
{
    public int Id

    public virtual ICollection<Company> Companies { get; set; }

    public int ActiveCompanyId { get; set; }

    [NotMapped]
    public Company ActiveCompany
    {
        get
        {
          return this.Companys == null ? null :
                      Companies.Where(x => x.Id == this.Active.CompanyId)
                               .SingleOrDefault;
        }
    }

    public User()
    {
       this.Companies = new HashSet<Company>();
    }
}

答案 1 :(得分:0)

您可以尝试以下映射吗?

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Company>()
        .HasMany(c => c.Users)
        .WithMany(u => u.Comapnies)
        .Map(x =>
        {
            x.MapLeftKey("CompanyId");
            x.MapRightKey("UserId");
            x.ToTable("UserCompany");
        });

    modelBuilder.Entity<User>()
        .HasRequired(b => b.Company)
        .WithMany()
        .WillCascadeOnDelete(false);
}