Expose a repository as an IQueryable

前端 未结 5 1881
梦如初夏
梦如初夏 2021-01-21 20:58

I\'d like to expose a Repository as an \'IQueryable\' type.

The repository uses Linq to NHibernate to communicate with the database.

Can anyone point me at an ex

相关标签:
5条回答
  • 2021-01-21 21:14

    I think a Repository can give you 1 or more IQueryables/IEnumerables, but not : a Repository is an IQueryable.

    It could look like:

     public interface IPersonRepository
     {
        IEnumerable<Person> GetAllPersons();
        void AddPerson(Person person);
    
        // more...
     }
    

    You could return IQeryable<Person> from GetAllPerson() but that may not be an improvement. IEnumerable is simpler, less coupling.

    0 讨论(0)
  • 2021-01-21 21:30

    Lots of opinions of this one, but Ayende (Oren Eini) seems to think IQueryable is ok to return and articulates his point rather well.

    0 讨论(0)
  • 2021-01-21 21:31

    Just return session.Linq<T>()

    0 讨论(0)
  • 2021-01-21 21:33

    This is a bad design.

    An IQueryable is a question (lookup "query" in a dictionary). It's how you ask for data. It's what you should be giving to the Repository.

    A Repository should be returning answers -- the data itself.

    If the Repository is returning a IQueryable, you've pretty much negated the need for the Repository.

    0 讨论(0)
  • 2021-01-21 21:35

    I can see two possible solutions here:

    1. Expose IEnumerable and use .AsQueryable() when needed

      // Repository
      public IEnumerable<Person> GetAll() {
          return _dbContext.People.AsQueryable();
      }
      
      // Usage
      public Person GetByPhone(string phoneNumber) {
          var queryablePeople = _personRepository.GetAll().AsQueryable();
          return queryablePeople.FirstOrDefault(perspn => person.Phone == phoneNumber);
      }
      
    2. Accept expression in Repository method

      // Repository
      public IEnumerable<Person> GetPeople(Expression<Func<Person, bool>> filter) {
          return _dbContext.People.Where(filter);
      }
      
      // Usage
      public Person GetByPhone(string phoneNumber) {
          return _personRepository.GetPeople(person => person.Phone == phoneNumber).FirstOrDefault();
      }
      

    Note: Not any expression filter can be translated to SQL Query by Entity Framework

    0 讨论(0)
提交回复
热议问题