I am building a domain model that requires several tables to be able to be references by more than one possible parent table. Something like you might have a table to store notes or files and those notes and/or files can be associated with different parent entities. Not that the same "file" or "note" can be associate with multiple owners, but that of 10 rows in a "files" table, 3 of them might be owned by rows from a "Customer" table, 3 of them might be owned by rows from an "Orders" table, and 4 of them might be owned by rows from a "Person" table.
The owning tables all have virtual ICollections of the child tables.
When I ran my model through the code first migration for the initial migration, and looked at the generated fluent code, the table definition for these tables included multiple id columns that referred back to the source table, so that there would be a column "customer_id," "person_id," etc. (one for each possible "owning entity." This doesn't seem quite "right." Is there a better way to model this in EF with CodeFirst? Like being able to use a discriminator column in the child table that provides a "hint" about the owning entity?
Thanks,
-MrB
If you create a many-to-many relationship between notes and all entities that can have notes, you will have a junction table for each owning type and a nice and clean note table. The simplest way to create the many-to-many relationships is to override the DbContext.OnModelCreating
method.
Your DbContext:
public class MyDatabase : DbContext
{
// Protected methods
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Customer>().HasMany(x => x.Notes).WithMany();
modelBuilder.Entity<Order>().HasMany(x => x.Notes).WithMany();
}
public MyDatabase() : base("MyDatabase")
{
}
// Properties
public DbSet<Customer> Customers { get; set; }
public DbSet<Order> Orders { get; set; }
public DbSet<Note> Notes { get; set; }
}
This will produce the following tables: Customer, Orders, Notes, CustomerNotes and OrderNotes with the last two being junction tables with only two columns each.
NOTE! With this solution it is also possible for entities to share notes, e.g. a Customer and an Order can own the same Note.
Not sure if fits but you could use EF hierarchies to do it. See This article:
http://weblogs.asp.net/manavi/archive/2010/12/24/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part-1-table-per-hierarchy-tph.aspx
Basically you could have three types for your notes all inheriting from a basic note type.
There are three types of hierarchies in EF so its a three partes article...