我想将Repository暴露为'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();
}
}
答案 0 :(得分:4)
我认为存储库可以为您提供 1个或更多IQueryables / IEnumerables,但不是:存储库 是IQueryable。
它可能看起来像:
public interface IPersonRepository
{
IEnumerable<Person> GetAllPersons();
void AddPerson(Person person);
// more...
}
你可以从GetAllPerson()返回IQeryable<Person>
,但这可能不是一个改进。 IEnumerable更简单,耦合更少。
答案 1 :(得分:4)
这是一个糟糕的设计。
IQueryable
是一个问题(在字典中查找“查询”)。这就是你要求数据的方式。这就是你应该将提供给存储库。
存储库应该返回答案 - 数据本身。
如果Repository返回了IQueryable,那么你几乎不需要存储库。
答案 2 :(得分:2)
对这一点有很多意见,但Ayende (Oren Eini)似乎认为IQueryable is ok要回归并清楚表达他的观点。
答案 3 :(得分:1)
只需返回session.Linq<T>()
答案 4 :(得分: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);
}
使用存储库方法接受表达式
// 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查询