簡體   English   中英

通用存儲庫包含和過濾

[英]Generic Repository Includes and Filtering

我創建了一個通用存儲庫。 目前,我有一個StaffRepository,它繼承自我的通用資源庫(資源庫)。 這很好用,因為我的通用存儲庫具有我的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中的所有代碼,因為這不是此問題的一部分。 謝謝

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM