我想将存储库公开为'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();
}
}
这是一个糟糕的设计。
IQueryable
是一个问题(在字典中查找“查询”)。这就是您要求数据的方式。这就是您应该提供到存储库的内容。
存储库应该返回答案-数据本身。
如果存储库返回一个IQueryable,则您几乎不需要存储库。
我认为存储库可以给您 1个或多个IQueryables / IEnumerables,但不是:存储库is一个IQueryable。
它可能看起来像:
public interface IPersonRepository
{
IEnumerable<Person> GetAllPersons();
void AddPerson(Person person);
// more...
}
您可以从GetAllPerson()返回IQeryable<Person>
,但这可能不是一个改进。 IEnumerable更简单,耦合更少。
[关于这一观点的很多观点,但是Ayende (Oren Eini)似乎认为IQueryable is ok回来了,并很好地阐明了他的观点。
仅返回session.Linq<T>()
我可以在这里看到两个可能的解决方案:
公开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);
}
存储库方法中的接受表达式
// 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查询