Can I specify global mapping rules in Entity Framework Code First?

前端 未结 2 979
不知归路
不知归路 2020-11-27 08:27

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

相关标签:
2条回答
  • 2020-11-27 09:20

    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).

    0 讨论(0)
  • 2020-11-27 09:26

    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 EntityTypeConfigurations. 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
      ...
    }
    

    NOTE:

    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/

    0 讨论(0)
提交回复
热议问题