【问题标题】:2 Foreign Keys, 1 Navigation Property to pull through both2 个外键,1 个导航属性,可通过两者
【发布时间】:2017-04-21 10:22:05
【问题描述】:

鉴于以下粗略的代码优先架构,目标似乎很简单。 Invoice 可以来自或发往CompanyInvoices 集合应包含所有发票,无论它是哪个发票。

public class Company
{
    public int Id { get; set; }
    public virtual ICollection<Invoice> Invoices { get; set; }
}

public class Invoice
{
    public int Id { get; set; }
    public int FromCompanyId { get; set; }
    public int ToCompanyId { get; set; }
    public virtual Company FromCompany { get; set; }
    public virtual Company ToCompany { get; set; }
}

您会在迁移中注意到,生成第三个 Company_Id 的原因很明显,以支持 Invoices 导航属性,因为仅 EF似乎支持 1 Nav Prop -> 1 FK安排。

我的问题是是否可以让Invoices 属性同时包含两者,或者我是否应该单独映射它们(即IC&lt;Inv&gt; InvoicesFromIC&lt;Inv&gt; InvoicesTo)并创建一个客户端集合以同时包含两者手动。

我试过了:

  1. FromCompanyToCompany 上都使用InverseProperty,这会使EF 感到困惑,因为它无法确定关系的主体端。

    [ForeignKey(nameof(FromCompanyId)), InverseProperty(nameof(Company.Invoices))]
    public virtual Company FromCompany { get; set; }
    [ForeignKey(nameof(ToCompanyId)), InverseProperty(nameof(Company.Invoices))]
    public virtual Company ToCompany { get; set; }
    
  2. 使用 fluent API 来映射它们,但它只考虑第二个,这从代码的角度来看是有意义的。

        modelBuilder.Entity<Company>()
            .HasMany(m => m.Invoices)
            .WithRequired(m => m.ToCompany)
            .WillCascadeOnDelete(false);
        modelBuilder.Entity<Company>()
            .HasMany(m => m.Invoices)
            .WithRequired(m => m.FromCompany)
            .WillCascadeOnDelete(false);
    

如果这不可能,当然没有什么大问题,我可以发誓我以前做过。

【问题讨论】:

    标签: c# entity-framework ef-code-first poco


    【解决方案1】:

    为了后代,这里是一个完整版本的解决方法,用于维护来自公司的IEnumerable&lt;Invoices&gt;,其中包含两个集合。

    public class MyContext : DbContext
    {
        public MyContext() : base("DefaultConnection") { }
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
    
            modelBuilder.Entity<Company>().HasMany(c => c.InvoicesFrom).WithRequired(i => i.FromCompany).WillCascadeOnDelete(false);
            modelBuilder.Entity<Company>().HasMany(c => c.InvoicesTo).WithRequired(i => i.ToCompany).WillCascadeOnDelete(false);
        }
    
        public DbSet<Company> Companies { get; set; }
        public DbSet<Invoice> Invoices { get; set; }
    }
    
    public class Company
    {
        public int Id { get; set; }
        public virtual ICollection<Invoice> InvoicesFrom { get; set; }
        public virtual ICollection<Invoice> InvoicesTo { get; set; }
    
        [NotMapped]
        public IEnumerable<Invoice> Invoices
        {
            get {
                return InvoicesFrom.Union(InvoicesTo);
            }
        }
    }
    
    public class Invoice
    {
        public int Id { get; set; }
        public int FromCompanyId { get; set; }
        public int ToCompanyId { get; set; }
        public virtual Company FromCompany { get; set; }
        public virtual Company ToCompany { get; set; }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-07
      • 2018-02-19
      相关资源
      最近更新 更多