2016-12-06 1 views
1

Учитывая следующую грубую кодовую схему, цель будет казаться довольно простой. Номер Invoice может быть от или до Company, а коллекция Invoices должна содержать все счета-фактуры, независимо от того, какая из них.2 Внешние ключи, 1 свойство навигации, чтобы вытащить оба из них

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<Inv> InvoicesFrom, IC<Inv> InvoicesTo) и создать коллекцию на стороне клиента, чтобы иметь как вручную.

Я попытался:

  1. Использование InverseProperty на обоих FromCompany и ToCompany, который путает 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. Использование свободно 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); 
    

Там нет, конечно, не главная проблема, если это не возможно, я просто не мог бы поклясться, что я сделал это раньше.

ответ

0

Для потомков здесь приведена полная версия обходного пути для поддержки 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; } 
} 
Смежные вопросы