gpt4 book ai didi

c# - 通用存储库包含和过滤

转载 作者:行者123 更新时间:2023-12-02 20:31:20 27 4
gpt4 key购买 nike

我已经创建了一个通用存储库。目前,我有一个 StaffRepository 继承 self 的通用存储库(Repository)。这很有效,因为我的通用存储库具有我的 CRUD 操作,并允许我在我的服务中使用这些操作以及我的 StaffRepository 中的方法,这些方法对上下文进行额外的过滤并添加包含。但是,我需要为每个实体创建一个存储库(大多数按 ClientId 和主键过滤)。有没有一种方法可以使用通用方法来过滤和应用包含?我也在这里应用正确的方法吗?感谢您的帮助。

示例 StaffRepository:

 public class StaffRepository : Repository<Staff>
{
public StaffRepository(ApplicationDbContext _context) : base(_context)
{
}

public async Task<List<Staff>> GetAsync(int clientId)
{
return await _context.Staff
.Include(s => s.Person)
.Include(u => u.Person.User)
.Include(p => p.Photograph)
.Where(x => x.ClientId == clientId)
.ToListAsync();
}

public async Task<Staff> GetByIdAsync(int clientId, int staffId)
{
return await _context.Staff
.Include(s => s.Person)
.Include(u => u.Person.User)
.FirstOrDefaultAsync(x => x.ClientId == clientId && x.StaffId == staffId);
}
}

我的通用存储库:

public class Repository<T> : IRepository<T> where T : class, new()
{
internal readonly ApplicationDbContext _context;

public Repository(ApplicationDbContext context)
{
this._context = context;
}

public async Task<T> FindAsync(int id)
{
return await _context.Set<T>().FindAsync(id);
}

public async Task InsertAsync(T entity)
{
await _context.Set<T>().AddAsync(entity);
await SaveAsync();
}

public async Task AddRangeAsync(IEnumerable<T> entities)
{
await _context.Set<T>().AddRangeAsync(entities);
await SaveAsync();
}

public async Task UpdateAsync(T entity)
{
_context.Set<T>().Attach(entity);
_context.Entry(entity).State = EntityState.Modified;
await SaveAsync();
}

public async Task DeleteAsync(T entity)
{
if (_context.Entry(entity).State == EntityState.Detached)
_context.Set<T>().Attach(entity);
_context.Set<T>().Remove(entity);
await SaveAsync();
}

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

最佳答案

您需要做的就是使用表达式,就像您在下面的 GetAsync 方法中看到的那样:

public class GenericRepository<TEntity> where TEntity : class
{
internal DbContext dbContext;
internal DbSet<TEntity> dbSet;

public GenericRepository(DbContext context)
{
this.dbContext = context;
this.dbSet = context.Set<TEntity>();
}

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

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

if (offset > 0)
{
query = query.Skip(offset);
}
if (first > 0)
{
query = query.Take(first);
}

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();
}
}
}

我刚刚将我的存储库包含在 GetAsync 方法中,我会建议您使用 UnityOfWork 模式,这样您就可以将此存储库的实例(针对每个实体)放在一个集中的位置,例如:

public class UnitOfWork : IDisposable
{
private GenericRepository<YourEntity> yourRepository;

private DbContext context;

public UnitOfWork(DbContext context)
{
this.context = context;
}

public GenericRepository<YourEntity> YourRepository
{
get
{
if (this.yourRepository== null)
{
this.yourRepository= new GenericRepository<YourEntity>(context);
}
return yourRepository;
}
}
}

那么这只是一个如何实例化它的例子:

await unitOfWork.YourRepository.GetAsync(filter: w => w.OtherKeyNavigation.Id == 123456, includeProperties: "OtherKeyNavigation", first: 20, offset: 0);

注意:我没有包括存储库和 UnityOfWork 中的所有代码,因为这不是这个问题的一部分。谢谢

关于c# - 通用存储库包含和过滤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48671263/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com