鉴于以下粗略的代码优先架构,目标看起来非常简单。 Invoice
可以来自Company
,也可以Invoices
,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
以支持Invoices
导航属性,因为仅 以支持1 Nav Prop - &GT; 1 FK安排。
我的问题是,是否可以让IC<Inv> InvoicesFrom
属性包含两者,或者我是否应该单独映射它们(即IC<Inv> InvoicesTo
,InverseProperty
)并创建客户端 - 手动收集。
我试过了:
在FromCompany
和ToCompany
上使用[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; }
会混淆EF,因为它无法确定关系的主要结束。
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);
使用流畅的API来映射它们,但它只考虑从代码角度来看的第二个。
{{1}}
如果不可能的话,当然没有重大问题,我可以发誓我以前做过。
答案 0 :(得分:1)
对于后代,这里是一个完整版本的变通方法,用于维护包含两个集合在一起的公司的IEnumerable<Invoices>
。
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; }
}