I'm creating my first project using ASP.NET Core and Dapper. Before this project I used Entity Framework. DAL in my past projects was like this:
// Project.Data
public class BaseRepository : IDisposable
{
public string ConnectionString { get; set; }
protected BaseRepository()
{
}
protected BaseRepository(string connectionString)
{
ConnectionString = connectionString;
}
protected string GetConnectionStringValue(string connectionStringName)
{
...
}
}
// Project.Data.EF
public abstract class EntityBaseRepository : BaseRepository
{
private DbContext _context;
protected EntityBaseRepository(): base("connectionString")
{
}
protected DbContext Context => _context ?? (_context = CreateEntityContext(GetConnectionStringValue(ConnectionString)));
protected abstract DbContext CreateEntityContext(string connectionString);
protected virtual void SaveEntity<T>(T entity) where T : Entity
{
...
}
protected virtual void DeleteEntity<T>(T entity) where T : Entity
{
...
}
}
public abstract class EntityBaseRepository<TEntity, TSearchOptions, TLoadOptions> : EntityBaseRepository
where TEntity : Entity
where TSearchOptions : SearchOptions
where TLoadOptions : LoadOptions
{
protected IEnumerable<TEntity> GetEntities(TSearchOptions searchOptions, TLoadOptions loadOptions)
{
...
}
protected async Task<IEnumerable<TEntity>> GetEntitiesAsync(TSearchOptions searchOptions, TLoadOptions loadOptions)
{
...
}
protected int GetCount(TSearchOptions searchOptions)
{
...
}
protected TEntity GetEntity(long id, TLoadOptions loadOptions)
{
...
}
protected virtual IQueryable<TEntity> ApplySearchOptions(
DbContext context, IQueryable<TEntity> entities, TSearchOptions searchOptions)
{
...
}
protected virtual IQueryable<TEntity> ApplyLoadOptions(
DbContext context, IQueryable<TEntity> entities, TLoadOptions loadOptions)
{
...
}
}
I thought I can use this approach with dapper. I have created mapper for entities and query builder. After that I have created Repository:
public abstract class EntityBaseRepository<TEntity, TKey, TSearchOptions, TLoadOptions> : EntityBaseRepository
where TEntity : Entity<TKey>
where TSearchOptions : SearchOptions
where TLoadOptions : LoadOptions
{
...
protected virtual Query ApplySearchOptions(QueryBuilder query, TSearchOptions searchOptions)
{
if (searchOptions.IDs.Any())
query.WhereIn(FluentMapper.KeyColumnName<TEntity>().ToArray(), searchOptions.IDs);
return query;
}
protected virtual Query ApplyLoadOptions(QueryBuilder query, TLoadOptions loadOptions)
{
if (loadOptions.SortFields.Any())
{
foreach (var sortField in loadOptions.SortFields)
{
switch (sortField.Value)
{
case SortOrder.Ascending:
break;
case SortOrder.Descending:
break;
default:
throw new ArgumentOutOfRangeException();
}
}
}
if (loadOptions.SkipRecords.HasValue)
query.Skip(loadOptions.SkipRecords.Value);
if (loadOptions.MaxRecords.HasValue)
query.Take(loadOptions.MaxRecords.Value);
return query;
}
}
QueryBuilder is fluent query constructor (like sqlkata). The main problem when using this approach with Dapper is applying search and load options. I don't know how to do it properly. If in derived from EntityBaseRepository class I use alias (for example QueryBuilder.From("x as A")), I will receive exception.
How would you create DAL with dapper?
Aucun commentaire:
Enregistrer un commentaire