Should I return IEnumerable<T> or IQueryable<T> from my DAL?
我知道这可能是意见,但我正在寻找最佳实践。
据我了解,
1 2 3 | IEnumerable<Product> GetProducts(); IEnumerable<Product> GetProductsByCategory(int cateogoryId); Product GetProduct(int productId); |
我应该在这里使用
这两种方法的优缺点是什么?
请注意,我正计划使用存储库模式,因此我将拥有这样的类:
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 )); } } |
我应该把我的
这取决于你想要什么行为。
- 安全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
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
这是一个位的一个judgement打电话,你给你的应用程序的linq力量,有更少的复杂性和在库,或你的数据访问控制。为我这取决于与每个相关的数量的queries entity,和实体的组合,和在哪里,我想manage的复杂性。