关于linq to sql:我应该返回IEnumerable< T>

Should I return IEnumerable<T> or IQueryable<T> from my DAL?

我知道这可能是意见,但我正在寻找最佳实践。

据我了解,IQueryable实现IEnumerable,因此在我的DAL中,我目前有如下方法签名:

1
2
3
IEnumerable<Product> GetProducts();
IEnumerable<Product> GetProductsByCategory(int cateogoryId);
Product GetProduct(int productId);

我应该在这里使用IQueryable吗?

这两种方法的优缺点是什么?

请注意,我正计划使用存储库模式,因此我将拥有这样的类:

1
2
3
4
5
6
7
8
9
public class ProductRepository {

    DBDataContext db = new DBDataContext(<!-- connection string -->);

    public IEnumerable<Product> GetProductsNew(int daysOld) {
        return db.GetProducts()
          .Where(p => p.AddedDateTime > DateTime.Now.AddDays(-daysOld ));
    }
}

我应该把我的IEnumerable改成IQueryable吗?其中一个或另一个有什么优点/缺点?


这取决于你想要什么行为。

  • 安全returning ilist<T >的caller告诉,他们已经获得了所有他们已经设计了数据
  • returning ienumerable > <不安全的,他们会告诉caller需要iterate在该lazily loaded和它可能的结果。
  • 安全returning iqueryable<T > caller告诉的,结果是支持的由一个linq provider,可以处理的类的queries一定的负担,把对performant caller形成一个查询。

而在后者的caller给出了很多flexibility(假设你的库充分支持它),它是大的和艰难的测试,arguably deterministic,至少。


再一件事想约:哪里是你的paging sorting /支持?如果你是在你的paging库提供的支持,returning IEnumerable美好。如果你是paging外库(如:你在控制器或服务层),然后你真的想使用IQueryable,因为你不想load整个内存的dataset成它的paged之前。


huuuuggge分。我看到这一点相当。

你建立起来的数据库安全iqueryable H.I.T.s之前它。只有一次的iqueryable H.I.T.s eager分贝的安全功能是被称为().tolist(例如)或你真的尝试拉出来的价值。lazy iqueryable =。

你会安全的ienumerable execute马上对lambda分贝。eager ienumerable =。

作为与大的库,使用的模式,我相信这是eager。我通常看到的是别的ilists通过,但将需要铁,出来为你。编辑你通常看到ienumerable iqueryable而不是因为你不想要的图层determining过去库)的数据库时,会发生adding打或B)加入外的任何逻辑文献库

有一个很好的视频,我喜欢很多linq -它只是ienumerable V iqueryable H.I.T.s超过,但它真的有一些fantastic洞察力。

http:/ / / / / channel9.msdn.com帖子matthijs linq - tips -技巧-和-优化-由-斯科特-艾伦/


你可以使用iqueryable和accept,有人创造了一个可以在一个查询scenario可能发生在N + 1。这是一个disadvantage,随着的事实是,你可能结束了与大的代码库的具体实现,是在你的库层的上方。这是你的优点是允许的对像常见的作战paging和sorting表示:你respository外面的大,因此它的alleviating这样的关注。它是灵活的,如果你还需要更多的数据与其他数据库表连接的查询,以及将保持安全的表达,所以可以被添加到一个在其resolved H.I.T.s的查询和数据库。

替代的是锁下来你的所以它returns库materialised ToList()列出由电话。与paging和sorting的的例子,你将需要通过和那些在斯基,以表达作为参数的方法的参数和使用的库,只有一个窗口的大回报的结果。这意味着,该库是以对…的paging和sorting疏散,和所有的你的数据。

这是一个位的一个judgement打电话,你给你的应用程序的linq力量,有更少的复杂性和在库,或你的数据访问控制。为我这取决于与每个相关的数量的queries entity,和实体的组合,和在哪里,我想manage的复杂性。