Entity Framework 4.1 Generic Repository set up

后端 未结 1 1564
名媛妹妹
名媛妹妹 2021-01-17 02:22

I\'m new to Entity Framework and joined a project that uses a generic repository as shown below. Are there any disadvantages to the way the repository is set up? I\'ve notic

相关标签:
1条回答
  • 2021-01-17 03:01

    The main disadvantage of using a generic repository instead of having a concrete repository implementation per Aggregate root, is that you cannot create specific methods for specific usages.

    Having all your repositories inherit from a base repository let you create methods like: GetProductsInsSock() or things like UpdateOnlyProductsThatSatisfySomething().

    But some workarounds are available! ;-)

    Keep on using your generic repository if it suits to your team, the only thing you might have to add is a method that accept a Specification as parameter. As Eric Evans and Martin Fowler say:

    The central idea of Specification is to separate the statement of how to match a candidate, from the candidate object that it is matched against.

    In your case it could work as a filter to retrieve the right entities without having the need to create a specific method.

    You could simply add this to your IRepository interface:

    IEnumerable<T> Find(Specification<T> predicate);
    

    The method implementation in your Repository class would be like this:

    public class Repository<T> : IRepository<T> where T : class
    {
      public Repository(IDbContext context)
      {
        _context = context;
        _dbset   = context.Set<T>();
      }
    
      // some code...
    
      public IEnumerable<T> Find(Specification<T> specification)
      {
        return _dbset.Where(specification.Predicate);
      }
    
      // some code...
    }
    

    The Specification class could look like this:

    public class Specification<T>
    {
      public Specification(Expression<System.Func<T, bool>> predicate)
      {
        _predicate = predicate;
      }
    
      internal Expression<System.Func<T, bool>> Predicate
      {
        get { return _predicate; }
      }
    
      private readonly Expression<System.Func<T, bool>> _predicate;
    }
    

    A call example:

    var specification = ProductSpecification.InStock();
    var product = Repository.Find(specification).FirstOrDefault();
    

    And finally, the ProductSpecification class:

    internal static class ActionSpecification
    {
      internal static Specification<Product> InStock()
      {
        return new Specification<Product>(p => p.IsInStock == true);
      }
    }
    
    0 讨论(0)
提交回复
热议问题