To utilize Dapper within the ABP framework, install the Abp.Dapper NuGet package alongside your primary ORM provider (such as Abp.EntityFrameworkCore for EF Core or Abp.NHibernate). Dapper serves as a lightweight supplementary ORM that operates alongside Entity Framework without conflicts.
Module Configuration
Register the Dapper module during application initialization. Ensure AbpDapperModule depends on the specific database ORM module to maintain correct dependency ordering.
[DependsOn(
typeof(AbpEntityFrameworkCoreModule),
typeof(AbpDapperModule)
)]
public class InfrastructureLayerModule : AbpModule
{
public override void Initialize()
{
IocManager.RegisterAssemblyByConvention(
Assembly.GetExecutingAssembly());
}
}
Entity Mapping Definition
Define table structures using the ClassMapper<T> pattern. This configuration handles SQL-specific mappings independent of the primary EF Core model definitions.
public class CustomerEntityMap : ClassMapper<CustomerEntity>
{
public CustomerEntityMap()
{
Table("Customers");
Map(x => x.Orders).Ignore(); // Avoid circular mapping issues
AutoMap();
}
}
After defining mappers, register the containing assembly so the framework can discover them at runtime.
public override void Initialize()
{
base.Initialize();
var mapperAssembly = typeof(CustomerEntityMap).Assembly;
DapperExtensions.DapperExtensions.SetMappingAssemblies(
new List<Assembly> { mapperAssembly });
// Override dialect if using MySQL/MariaDB
DapperExtensions.DapperExtensions.SqlDialect =
new MySqlDialect();
// Default behavior targets SqlServerDialect
}
Repository Injection and Usage
Inject the generic IDapperRepository<T> interface instead of the stendard IRepository<T>. This enables direct Dapper operations while preserving the existing UnitOfWork transaction scope managed by ABP.
public class OrderProcessingService : ITransientDependency
{
private readonly IRepository<Order> _efRepository;
private readonly IDapperRepository<Order> _dapperRepo;
public OrderProcessingService(
IRepository<Order> efRepo,
IDapperRepository<Order> dapperRepo)
{
_efRepository = efRepo;
_dapperRepo = dapperRepo;
}
public async Task RunComplexReports()
{
// Execute raw SQL queries efficiently via Dapper
var activeOrders = await _dapperRepo.QueryAsync(
"SELECT * FROM Orders WHERE Status = 'Active'");
// Standard EF Core operations remain functional
// within the same transaction context
}
}
By leveraging both repositories simultaneously, developers achieve high-performance read capabilities through Daper while retaining Entity Framework's change-tracking features for writes within the same unit of work.