首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用EF实现存储库而不创建多个实例方法

使用EF实现存储库而不创建多个实例方法
EN

Stack Overflow用户
提问于 2022-10-20 13:11:22
回答 3查看 72关注 0票数 1

多年来,我一直在没有存储库层的情况下在我的项目中使用EF核心,现在我决定为我的一个项目实现存储库模式,它变得非常大。我们有超过30个实体模型和一个庞大的API端点列表。

问题是,每个端点都从按前端需求格式化的DB返回所需的数据。有些时候,我们只想要一个实体的列表,而另一些时候,使用一些相关数据的相同的列表,有时使用一些SQL聚合函数来进行一些计算。

我们只是在每个端点中直接使用DBContext来执行我们需要的查询,但是在实现存储库时,我们遇到了一个困难,就是编写几种方法来使不同的数据格式化到我们的需要。不仅仅是基本的CRUD和更多的操作。

我的问题是,这实际上是如何完成的(根据需要创建更多的方法),或者有什么最佳实践吗?是否有某种方式“重写”DBContext,以便我可以使用表达式并将其转换为泛型,从而避免创建这么多的mach方法?

非常感谢!

EN

Stack Overflow用户

回答已采纳

发布于 2022-10-20 14:27:50

分享我的实际BaseRepo

代码语言:javascript
运行
复制
public class BaseRepository<TEntity> : IBaseRepository<TEntity> where TEntity : class
{
    internal ApplicationDbContext Context;
    internal DbSet<TEntity> dbSet;

    public BaseRepository(ApplicationDbContext context)
    {
        this.Context = context;
        this.dbSet = context.Set<TEntity>();
    }

    public virtual async Task AddAsync(TEntity entity)
    {
        await dbSet.AddAsync(entity);
        await SaveAsync();
    }

    public virtual async Task AddRangeAsync(IEnumerable<TEntity> entities)
    {
        await dbSet.AddRangeAsync(entities);
        await SaveAsync();
    }

    public virtual async Task<IEnumerable<TEntity>> GetAllAsync()
    {
        return await dbSet.ToListAsync();
    }

    public virtual async Task<IEnumerable<TEntity>> GetAsync(Expression<Func<TEntity, bool>> filter = null, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null, string includeProperties = "")
    {
        IQueryable<TEntity> query = dbSet;

        if (filter != null)
            query = query.Where(filter);

        foreach (var includeProperty in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
        {
            query = query.Include(includeProperty);
        }

        if (orderBy != null)
            return await orderBy(query).ToListAsync();
        else
            return await query.ToListAsync();
    }

    public virtual async Task<TEntity> GetByIdAsync(int? id)
    {
        return await dbSet.FindAsync(id);
    }

    public async Task Remove(TEntity entity)
    {
        dbSet.Remove(entity);
        await SaveAsync();
    }

    public async Task RemoveRange(IEnumerable<TEntity> entities)
    {
        dbSet.RemoveRange(entities);
        await SaveAsync();
    }

    public virtual async Task<TEntity> SingleOrDefaultAsync(Expression<Func<TEntity, bool>> predicate)
    {
        return await dbSet.SingleOrDefaultAsync(predicate);
    }

    public virtual async Task Update(TEntity entityToUpdate)
    {
        dbSet.Attach(entityToUpdate);
        Context.Entry(entityToUpdate).State = EntityState.Modified;
        await SaveAsync();
    }

    public virtual async Task UpdateRange(IEnumerable<TEntity> entitiesToUpdate)
    {
        dbSet.AttachRange(entitiesToUpdate);
        Context.Entry(entitiesToUpdate).State = EntityState.Modified;
        await SaveAsync();
    }

    public async Task SaveAsync()
    {
        await Context.SaveChangesAsync();
    }

    public virtual async Task AddUpdateOrDeleteRange(IEnumerable<TEntity> entitiesToAddOrUpdate)
    {
        await Context.BulkInsertOrUpdateOrDeleteAsync<TEntity>(entitiesToAddOrUpdate.ToList(), new BulkConfig { SetOutputIdentity = false });
        await SaveAsync();
    }
    public virtual async Task AddOrUpdateRange(IEnumerable<TEntity> entitiesToAddOrUpdate)
    {
        await Context.BulkInsertOrUpdateAsync<TEntity>(entitiesToAddOrUpdate.ToList(), new BulkConfig { SetOutputIdentity = false });
        await SaveAsync();
    }
}

大容量的是EFCore.BulkExtensions的扩展;

工作单位

代码语言:javascript
运行
复制
public class UnitOfWork : IUnitOfWork, IDisposable, IAsyncDisposable
{
    private readonly ApplicationDbContext _context;
    private ExampleRepository _exampleRepository;

    IDisposable _disposableResource = new MemoryStream();
    IAsyncDisposable _asyncDisposableResource = new MemoryStream();

    public UnitOfWork(ApplicationDbContext context)
    {
        _context = context;
    }
    public IExampleRepository ExampleRepository=> _exampleRepository = _exampleRepository ?? new ExampleRepository(_context);

    public async Task<int> CommitAsync()
    {
        return await _context.SaveChangesAsync();
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    public async ValueTask DisposeAsync()
    {
        await DisposeAsyncCore();
        Dispose(disposing: false);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            _disposableResource?.Dispose();
            (_asyncDisposableResource as IDisposable)?.Dispose();
        }

        _disposableResource = null;
        _asyncDisposableResource = null;
    }

    protected virtual async ValueTask DisposeAsyncCore()
    {
        if (_asyncDisposableResource is not null)
        {
            await _asyncDisposableResource.DisposeAsync().ConfigureAwait(false);
        }

        if (_disposableResource is IAsyncDisposable disposable)
        {
            await disposable.DisposeAsync().ConfigureAwait(false);
        }
        else
        {
            _disposableResource?.Dispose();
        }

        _asyncDisposableResource = null;
        _disposableResource = null;
    }
}

ApplicationDbContext:

代码语言:javascript
运行
复制
public class ApplicationDbContext : DbContext
{
    public DbSet<Example> Examples { get; set; }
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { }

    protected override void OnModelCreating(ModelBuilder modelBuilder) 
    {
    }
}

希望你能帮上忙!

票数 1
EN
查看全部 3 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74140462

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档