Entity Framework Core Integration Best Practices
See Entity Framework Core Integration document for the basics of the EF Core integration.
- Do define a separated
DbContext
interface and class for each module. - Do not rely on lazy loading on the application development.
- Do not enable lazy loading for the
DbContext
.
DbContext Interface
- Do define an interface for the
DbContext
that inherits fromIEfCoreDbContext
. - Do add a
ConnectionStringName
attribute to theDbContext
interface. - Do add
DbSet<TEntity>
properties to theDbContext
interface for only aggregate roots. Example:
DbContext class
- Do inherit the
DbContext
from theAbpDbContext<TDbContext>
class. - Do add a
ConnectionStringName
attribute to theDbContext
class. - Do implement the corresponding
interface
for theDbContext
class. Example:
Table Prefix and Schema
- Do add static
TablePrefix
andSchema
properties to theDbContext
class. Set default value from a constant. Example:
- Do always use a short
TablePrefix
value for a module to create unique table names in a shared database.Abp
table prefix is reserved for ABP core modules. - Do set
Schema
tonull
as default.
Model Mapping
- Do explicitly configure all entities by overriding the
OnModelCreating
method of theDbContext
. Example:
- Do not configure model directly in the
OnModelCreating
method. Instead, create an extension method forModelBuilder
. Use ConfigureModuleName as the method name. Example:
- Do call
b.ConfigureByConvention();
for each entity mapping (as shown above). - Do create a configuration options class by inheriting from the
AbpModelBuilderConfigurationOptions
. Example:
Repository Implementation
- Do inherit the repository from the
EfCoreRepository<TDbContext, TEntity, TKey>
class and implement the corresponding repository interface. Example:
- Do use the
DbContext
interface as the generic parameter, not the class. - Do pass the
cancellationToken
to EF Core using theGetCancellationToken
helper method. Example:
GetCancellationToken
fallbacks to the ICancellationTokenProvider.Token
to obtain the cancellation token if it is not provided by the caller code.
- Do create a
IncludeDetails
extension method for theIQueryable<TEntity>
for each aggregate root which has sub collections. Example:
- Do use the
IncludeDetails
extension method in the repository methods just like used in the example code above (see FindByNormalizedUserNameAsync).
- Do override
WithDetails
method of the repository for aggregates root which have sub collections. Example:
Module Class
- Do define a module class for the Entity Framework Core integration package.
- Do add
DbContext
to theIServiceCollection
using theAddAbpDbContext<TDbContext>
method. - Do add implemented repositories to the options for the
AddAbpDbContext<TDbContext>
method. Example: