将存储库公开为IQueryable

问题描述 投票:2回答:5

我想将存储库公开为'IQueryable'类型。

存储库使用Linq进行NHibernate与数据库通信。

有人可以指出示例实现吗?

例如,我的存储库中相应的'GetEnumerator()'实现是什么样的?

编辑:

这样的东西合适吗?

public class MyTypeRepository : IEnumerable<MyType>
{        
    IEnumerator<MyType> IEnumerable<MyType>.GetEnumerator()
    {
        return Session.Linq<MyType>().GetEnumerator();
    }


    IEnumerator IEnumerable.GetEnumerator()
    {
        return ((IEnumerable<MyType>)this).GetEnumerator();
    }

}
c# .net linq iqueryable
5个回答
4
投票

这是一个糟糕的设计。

IQueryable是一个问题(在字典中查找“查询”)。这就是您要求数据的方式。这就是您应该提供到存储库的内容。

存储库应该返回答案-数据本身。

如果存储库返回一个IQueryable,则您几乎不需要存储库。


4
投票

我认为存储库可以给您 1个或多个IQueryables / IEnumerables,但不是:存储库is一个IQueryable。

它可能看起来像:

 public interface IPersonRepository
 {
    IEnumerable<Person> GetAllPersons();
    void AddPerson(Person person);

    // more...
 }

您可以从GetAllPerson()返回IQeryable<Person>,但这可能不是一个改进。 IEnumerable更简单,耦合更少。


2
投票

[关于这一观点的很多观点,但是Ayende (Oren Eini)似乎认为IQueryable is ok回来了,并很好地阐明了他的观点。


1
投票

仅返回session.Linq<T>()


0
投票

我可以在这里看到两个可能的解决方案:

  1. 公开IEnumerable并在需要时使用.AsQueryable()

    // 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. 存储库方法中的接受表达式

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

注意:实体框架不能将任何表达式过滤器转换为SQL查询

© www.soinside.com 2019 - 2024. All rights reserved.