title: Generic Repository Includes and Filtering
body: <p>I have created a generic Repository.  At the moment I have a StaffRepository that inherits from my generic one (Repository).
  This works well, as my generic Repository has my CRUD operations and allows me to use these in my service aswell as the methods in my StaffRepository which does additional filtering on the context and adds includes.
  However, I need to create a Repository for each entity, (Most filter by ClientId and the primary key). 
  Is there a way I can use a generic approach for both the filtering and applying the includes?
  Also am I applying the right approach here? Thanks for your help.</p>
  
  <p>Example StaffRepository:</p>
  
  <pre><code> public class StaffRepository : Repository&lt;Staff&gt;
  {
      public StaffRepository(ApplicationDbContext _context) : base(_context)
      {
      }
  
      public async Task&lt;List&lt;Staff&gt;&gt; GetAsync(int clientId)
      {
          return await _context.Staff
              .Include(s =&gt; s.Person)
              .Include(u =&gt; u.Person.User)
              .Include(p =&gt; p.Photograph)
              .Where(x =&gt; x.ClientId == clientId)
              .ToListAsync();
      }
  
      public async Task&lt;Staff&gt; GetByIdAsync(int clientId, int staffId)
      {
          return await _context.Staff
              .Include(s =&gt; s.Person)
              .Include(u =&gt; u.Person.User)
              .FirstOrDefaultAsync(x =&gt; x.ClientId == clientId &amp;&amp; x.StaffId == staffId);
      }
  }
  </code></pre>
  
  <p>My Generic Repository:</p>
  
  <pre><code>public class Repository&lt;T&gt; : IRepository&lt;T&gt; where T : class, new()
  {
      internal readonly ApplicationDbContext _context;
  
      public Repository(ApplicationDbContext context)
      {
          this._context = context;
      }
  
      public async Task&lt;T&gt; FindAsync(int id)
      {
          return await _context.Set&lt;T&gt;().FindAsync(id);
      }
  
      public async Task InsertAsync(T entity)
      {
          await _context.Set&lt;T&gt;().AddAsync(entity);
          await SaveAsync();
      }
  
      public async Task AddRangeAsync(IEnumerable&lt;T&gt; entities)
      {
          await _context.Set&lt;T&gt;().AddRangeAsync(entities);
          await SaveAsync();
      }
  
      public async Task UpdateAsync(T entity)
      {
          _context.Set&lt;T&gt;().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&lt;T&gt;().Attach(entity);
          _context.Set&lt;T&gt;().Remove(entity);
          await SaveAsync();
      }
  
      public async Task SaveAsync()
      {
          await _context.SaveChangesAsync();
      }
  }
  </code></pre>