I\'m building an app in ASP.NET MVC 4 using Entity Framework Code First, and for simplicity I\'m inheriting all models that will be stored in the database from a BaseEntity
Such a mapping - called Table-Per-Concrete-Type (TPC) inheritance mapping - only makes sense if you really want to leverage polymorphism, for example if you want to load a list of say 10 BaseEntity
objects and expect that the actual type gets materialized so that the list contains 3 User
entities and 7 Product
entities.
Would such a query ever have any business relevance in your application? Looking at your BaseEntity
I can only see that querying all objects that - for example - have been created at a specific date, no matter which type the object has (if it's derived from BaseEntity
), could be useful. Do you need that? Also keep in mind how complex such a query would be. The SQL must query for almost all tables in your database and then union the result.
I would use inheritance mapping only if it has a real business meaning (for instance: Person
which has meaningful properties like address, phone, email, etc. on its own and Employee
that is derived from Person
and adds a Salary
and HiredDate
property, etc.).
In your case I would use the BaseEntity
only as a base type of your entity classes and don't specify any mapping at all for this class. EF will still map the inherited properties, but as part of the User
and Product
entity, etc., not as its own entity. I wouldn't even call it "Base Entity" but ... I don't know... maybe EntityBase
(meaning: the base (class) of all entities, but not an entity itself).
It has been stated correctly that it's not necessary to do global mapping in this specific case, because EF will map the properties for each individual type as long as you don't make BaseEntity
part of the model.
But your question title is stated more generally and yes, it is possible to specify global mapping rules if you configure the mappings by EntityTypeConfiguration
s. It could look like this:
// Base configuration.
public abstract class BaseMapping<T> : EntityTypeConfiguration<T>
where T : BaseEntity
{
protected BaseMapping()
{
this.Map(m => m.MapInheritedProperties()); // OK, not necessary, but
// just an example
}
}
// Specific configurations
public class UserMapping : BaseMapping<User>
{ }
public class ProductMapping : BaseMapping<Product>
{ }
public class TempModelsContext : DbContext
{
// Add the configurations to the model builder.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Configurations.Add(new UserMapping());
modelBuilder.Configurations.Add(new ProductMapping());
}
// DbSets
...
}
As of Entity Framework 6 some of these mappings can also be solved by custom code first conventions: http://romiller.com/2013/01/29/ef6-code-first-configuring-unmapped-base-types/