简体   繁体   中英

Plymorphic Many to Many relationships in EF

I have a polymorphic collection on one entity type that contains a collection of objects that are the child types of it. the child types are all stored in different tables in the db.

I need to map this relationship in the fluent API so I can manage the cascades. Here's a sample of the entity structure I have ...

[Table("Reports", "Reporting")]
class Report
{
    [Key]
    public int Id { get; set; } 
    public virtual ICollection<Entry> Entries { get; set; }
}

abstract class Entry
{
   [Key]
   public int Id {  get; set; }
   public virtual ICollection<Report> Reports { get; set; }
}

[Table("InvoiceEntries", "Reporting")]
class InvoiceEntry : Entry
{
    public ICollection<Invoice> Invoices { get; set; }
}

... <other types> like InvoiceEntry each mapped to their own tables ...

In my model configuration I have ...

builder.Ignore<Entry>();

Update

As mentioned in the comments, there's a great answer here on polymorphic relationships ...

https://weblogs.asp.net/manavi/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part-3-table-per-concrete-type-tpc-and-choosing-strategy-guidelines

... My scenario is the "Table Per Concrete Type" one with a Many to Many Relationship as the polymorphic one.

Whilst that description is great it doesn't seem to cover this scenario

Huh ... ok that was strange ... so it turns out that this actually only works if you're nice enough to let it know when you have a derived type from the child base type that doesn't work this way.

Example ...

[Table("Reports", "Reporting")]
class Report
{
    [Key]
    public int Id { get; set; } 
    public virtual ICollection<Entry> Entries { get; set; }
}

abstract class Entry
{
   [Key]
   public int Id {  get; set; }
   public virtual ICollection<Report> Reports { get; set; }
}

[Table("InvoiceEntries", "Reporting")]
class InvoiceEntry : Entry
{
    public ICollection<Invoice> Invoices { get; set; }
}

class PaymentEntry
{
   [ForeignKey("Payment")]
   public int PaymentId { get;set; }

   public virtual Payment Payment { get; set; }
}

It turns out the issue there is that the report object needs to have that PaymentEntry sub typed mapped using the fluent API and the cascade turned off in order to prevent multiple cascade paths.

If all child types only have the InvoiceEntry style many to many mapping EF can figure it out by itself.

To avoid this either fluent script the other relationship to avoid the cascade problem or make all child types in to many to many relationships.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM