Documentation Index Fetch the complete documentation index at: https://mintlify.com/IntentArchitect/Intent.Modules.NET/llms.txt
Use this file to discover all available pages before exploring further.
The Intent.EntityFrameworkCore.Repositories module provides a complete repository pattern implementation for Entity Framework Core, including base repository classes, interfaces, and generated repository implementations for each domain entity.
Overview
This module generates:
Repository interfaces for each entity
Repository implementations using EF Core
Base repository class with common CRUD operations
Support for async and sync methods
Paged query support
Custom query methods
Stored procedure support
Installation
Intent.EntityFrameworkCore.Repositories
Key Components
Repository Base
The RepositoryBase<TDomain, TPersistence, TDbContext> class provides common repository operations:
public class RepositoryBase < TDomain , TPersistence , TDbContext > : IEFRepository < TDomain , TPersistence >
where TDomain : class
where TPersistence : class , TDomain
where TDbContext : DbContext , IUnitOfWork
{
protected readonly TDbContext _dbContext ;
public RepositoryBase ( TDbContext dbContext )
{
_dbContext = dbContext ?? throw new ArgumentNullException ( nameof ( dbContext ));
}
public IUnitOfWork UnitOfWork => _dbContext ;
// CRUD Operations
public virtual void Add ( TDomain entity )
{
GetSet (). Add (( TPersistence ) entity );
}
public virtual void Update ( TDomain entity )
{
GetSet (). Update (( TPersistence ) entity );
}
public virtual void Remove ( TDomain entity )
{
GetSet (). Remove (( TPersistence ) entity );
}
// Query Operations
public virtual async Task < TDomain ?> FindAsync (
Expression < Func < TPersistence , bool >> filterExpression ,
CancellationToken cancellationToken = default )
{
return await QueryInternal ( filterExpression )
. SingleOrDefaultAsync < TDomain >( cancellationToken );
}
public virtual async Task < List < TDomain >> FindAllAsync (
CancellationToken cancellationToken = default )
{
return await QueryInternal ( filterExpression : null )
. ToListAsync < TDomain >( cancellationToken );
}
public virtual async Task < List < TDomain >> FindAllAsync (
Expression < Func < TPersistence , bool >> filterExpression ,
CancellationToken cancellationToken = default )
{
return await QueryInternal ( filterExpression )
. ToListAsync < TDomain >( cancellationToken );
}
// Paged Queries
public virtual async Task < IPagedList < TDomain >> FindAllAsync (
int pageNo ,
int pageSize ,
CancellationToken cancellationToken = default )
{
var query = QueryInternal ( filterExpression : null );
return await ToPagedListAsync < TDomain >(
query ,
pageNo ,
pageSize ,
cancellationToken );
}
// Count and Existence
public virtual async Task < int > CountAsync (
Expression < Func < TPersistence , bool >> filterExpression ,
CancellationToken cancellationToken = default )
{
return await QueryInternal ( filterExpression ). CountAsync ( cancellationToken );
}
public virtual async Task < bool > AnyAsync (
Expression < Func < TPersistence , bool >> filterExpression ,
CancellationToken cancellationToken = default )
{
return await QueryInternal ( filterExpression ). AnyAsync ( cancellationToken );
}
protected virtual IQueryable < TPersistence > CreateQuery ()
{
return GetSet ();
}
protected virtual DbSet < TPersistence > GetSet ()
{
return _dbContext . Set < TPersistence >();
}
}
Entity Repository
For each domain entity, a specific repository is generated:
public interface ICustomerRepository : IEFRepository < Customer , Customer >
{
Task < Customer ?> FindByIdAsync ( Guid id , CancellationToken cancellationToken = default );
Task < List < Customer >> FindByIdsAsync ( Guid [] ids , CancellationToken cancellationToken = default );
}
public class CustomerRepository : RepositoryBase < Customer , Customer , ApplicationDbContext >, ICustomerRepository
{
public CustomerRepository ( ApplicationDbContext dbContext ) : base ( dbContext )
{
}
public async Task < Customer ?> FindByIdAsync ( Guid id , CancellationToken cancellationToken = default )
{
return await FindAsync ( x => x . Id == id , cancellationToken );
}
public async Task < List < Customer >> FindByIdsAsync ( Guid [] ids , CancellationToken cancellationToken = default )
{
return await FindAllAsync ( x => ids . Contains ( x . Id ), cancellationToken );
}
}
Usage Examples
Basic CRUD Operations
public class CustomerService
{
private readonly ICustomerRepository _repository ;
public CustomerService ( ICustomerRepository repository )
{
_repository = repository ;
}
public async Task < Customer > CreateCustomerAsync ( string name , string email )
{
var customer = new Customer ( name , email );
_repository . Add ( customer );
await _repository . UnitOfWork . SaveChangesAsync ();
return customer ;
}
public async Task < Customer ?> GetCustomerAsync ( Guid id )
{
return await _repository . FindByIdAsync ( id );
}
public async Task UpdateCustomerAsync ( Guid id , string name )
{
var customer = await _repository . FindByIdAsync ( id );
if ( customer != null )
{
customer . UpdateName ( name );
_repository . Update ( customer );
await _repository . UnitOfWork . SaveChangesAsync ();
}
}
public async Task DeleteCustomerAsync ( Guid id )
{
var customer = await _repository . FindByIdAsync ( id );
if ( customer != null )
{
_repository . Remove ( customer );
await _repository . UnitOfWork . SaveChangesAsync ();
}
}
}
Advanced Queries
// Filter with expression
var activeCustomers = await _repository . FindAllAsync (
x => x . IsActive && x . CreatedDate >= DateTime . UtcNow . AddMonths ( - 6 )
);
// Paged results
var pagedCustomers = await _repository . FindAllAsync (
pageNo : 1 ,
pageSize : 20
);
// Custom query with includes
var customersWithOrders = await _repository . FindAllAsync (
x => x . IsActive ,
query => query . Include ( x => x . Orders ). ThenInclude ( o => o . Items )
);
// Count
var customerCount = await _repository . CountAsync ( x => x . IsActive );
// Existence check
var emailExists = await _repository . AnyAsync ( x => x . Email == "test@example.com" );
Query Options
// Using query options for complex queries
var result = await _repository . FindAllAsync (
x => x . IsActive ,
query => query
. Include ( x => x . Orders )
. Where ( x => x . Orders . Any ())
. OrderByDescending ( x => x . CreatedDate )
. Take ( 10 )
);
// Paged with query options
var pagedResult = await _repository . FindAllAsync (
x => x . IsActive ,
pageNo : 1 ,
pageSize : 20 ,
queryOptions : query => query
. Include ( x => x . Orders )
. OrderBy ( x => x . Name )
);
Configuration Options
Add Synchronous Methods to Repositories
Adds the synchronous equivalents for repository asynchronous methods. When enabled, methods like Find(), FindAll(), Count() are generated alongside their async counterparts. Note: Synchronous methods are generally discouraged in modern applications. Use async methods when possible.Default: false
Stored Procedures
The module supports executing stored procedures through repositories:
public interface ICustomerRepository : IEFRepository < Customer , Customer >
{
Task < List < CustomerReportDto >> GetCustomerReportAsync ( DateTime fromDate , DateTime toDate );
}
public class CustomerRepository : RepositoryBase < Customer , Customer , ApplicationDbContext >, ICustomerRepository
{
public async Task < List < CustomerReportDto >> GetCustomerReportAsync (
DateTime fromDate ,
DateTime toDate )
{
var fromDateParam = new SqlParameter ( "@FromDate" , fromDate );
var toDateParam = new SqlParameter ( "@ToDate" , toDate );
return await _dbContext
. Set < CustomerReportDto >()
. FromSqlRaw ( "EXEC sp_GetCustomerReport @FromDate, @ToDate" , fromDateParam , toDateParam )
. ToListAsync ();
}
}
Paging Support
The module includes a IPagedList<T> interface and implementation:
public interface IPagedList < T >
{
int TotalCount { get ; }
int PageCount { get ; }
int PageNo { get ; }
int PageSize { get ; }
IList < T > Items { get ; }
}
public class PagedList < T > : IPagedList < T >
{
public PagedList ( int totalCount , int pageNo , int pageSize , IList < T > items )
{
TotalCount = totalCount ;
PageNo = pageNo ;
PageSize = pageSize ;
Items = items ;
PageCount = ( int ) Math . Ceiling ( totalCount / ( double ) pageSize );
}
public int TotalCount { get ; }
public int PageCount { get ; }
public int PageNo { get ; }
public int PageSize { get ; }
public IList < T > Items { get ; }
}
Data Contracts
When working with data contracts (DTOs mapped to database views or stored procedures), the module generates:
public interface ICustomerSummaryRepository : IEFRepository < CustomerSummaryDto , CustomerSummaryDto >
{
// Specialized query methods
}
public class CustomerSummaryRepository : RepositoryBase < CustomerSummaryDto , CustomerSummaryDto , ApplicationDbContext >, ICustomerSummaryRepository
{
public CustomerSummaryRepository ( ApplicationDbContext dbContext ) : base ( dbContext )
{
}
}
Dependency Injection
Repositories are automatically registered in the DI container:
services . AddScoped < ICustomerRepository , CustomerRepository >();
services . AddScoped < IOrderRepository , OrderRepository >();
// ... other repositories
Testing
Repositories can be easily mocked for unit testing:
public class CustomerServiceTests
{
[ Fact ]
public async Task CreateCustomer_ShouldAddToRepository ()
{
// Arrange
var mockRepository = new Mock < ICustomerRepository >();
var mockUnitOfWork = new Mock < IUnitOfWork >();
mockRepository . Setup ( x => x . UnitOfWork ). Returns ( mockUnitOfWork . Object );
var service = new CustomerService ( mockRepository . Object );
// Act
await service . CreateCustomerAsync ( "John Doe" , "john@example.com" );
// Assert
mockRepository . Verify ( x => x . Add ( It . IsAny < Customer >()), Times . Once );
mockUnitOfWork . Verify ( x => x . SaveChangesAsync ( default ), Times . Once );
}
}
Additional Resources