IEnumerable与IQueryable的业务逻辑或DAL返回类型
我知道之前已经问过这些问题,我首先会列出其中一些问题(到目前为止我已阅读过的):
正如你所看到的那样,关于这个主题的SO本身有一些很好的资源,但是有一个问题/部分的问题,我仍然不确定是否已经阅读了这些内容。
我主要关注IEnumerable和IQueryable问题,更具体地说是DAL和它的消费者之间的耦合 。
我已经找到了关于这两个接口的不同观点。 但是,我关注的是DAL返回IQueryable的含义。 据我所知,IQueryable建议/暗示有一个Linq提供商。 这是第一个问题 – 如果DAL突然需要来自非Linq提供的数据源,该怎么办? 以下方法可行,但它更像是黑客攻击吗?
public static IQueryable GetAll() { // this function used to use a L2S context or similar to return data // from a database, however, now it uses a non linq provider // simulate the non linq provider... List results = new List { new Product() }; return results.AsQueryable(); }
所以我可以使用AsQueryable()扩展,虽然我不承认确切知道这是做什么的? 我总是将IQueryables想象为底层表达式树,我们可以根据需要添加它们,直到我们准备好执行查询并获取结果。
我可以通过将函数的返回类型更改为IEnumerable来纠正此问题。 然后我可以从函数返回IQueryable,因为它inheritance了IEnumerable,并且我保持延迟加载。 我失去的是能够附加到查询表达式:
var results = SomeClass.GetAll().Where(x => x.ProductTypeId == 5);
返回IQueryable时,据我所知,这只会附加表达式。 返回IEnumerable时,尽管保持了延迟加载,但必须对表达式进行求值,以便将结果带入内存并枚举,以过滤掉不正确的ProductTypeIds。
其他人如何绕过这个?
最后一部分(对不起,我知道,真的很长的问题!)。
在我检查的所有问题中,我发现IEnumerable是最推荐的,但是延迟加载对datacontext可用的要求怎么样? 据我了解,如果你的函数返回IEnumerable,但是你返回IQueryable,那么IQueryable依赖于底层的datacontext。 因为此阶段的结果实际上是一个表达式,并且没有任何内容被带入内存,所以您不能保证DAL的/函数的使用者将执行查询,也不能保证。 那么我是否必须以某种方式保留结果来源的上下文实例? 这是工作单元模式发挥作用的方式/原因吗?
为清楚起见问题摘要(搜索“?”……):
- 如果使用IQueryable作为返回类型,您是否将UI /业务逻辑与Linq提供商紧密耦合?
- 如果您突然需要从非Linq提供的源返回数据,那么使用AsQueryable()扩展是一个好主意吗?
- 任何人都有一个很好的链接描述如何将标准列表转换为AsQueryable工作,它实际上做了什么?
- 如何处理业务逻辑为DAL提供的其他过滤要求?
- 似乎IEnumerable和IQueryable的延迟加载都需要维护底层提供者,我应该使用工作单元模式还是其他什么来处理这个问题?
非常感谢提前!
- 好吧,你并没有严格地与任何特定的提供商联系,但作为一种重新措辞:你不能轻易地测试代码,因为每个提供商都有不同的支持function(意思是:什么适用于一个可能不适用于另一个- 甚至像
.Single()
这样的东西 - 我不这么认为,如果你脑子里有任何关于不断变化的提供者的问题 – 见上文
- 它只提供了一个在任何lambdas上使用
.Compile()
的装饰包装器,.Compile()
使用LINQ-to-Objects。 注意LINQ-to-Objects比任何其他提供者都有更多的支持,所以这不会成为问题 – 除了它意味着使用这种方法的任何“模拟”都不会真正测试你的实际代码而且基本没有意义( IMO) - 是的,狡猾 – 见下文
- 是的,狡猾 – 见下文
就个人而言,我更喜欢定义良好的API,它采用已知参数并返回加载的 List
或IList
(或类似)结果; 这为您提供了一个可测试/可模拟的API,并且不会让您受到延迟执行(封闭连接地狱等)的支配。 它还意味着提供程序之间的任何差异都在内部处理,以实现数据层。 它还更适合调用Web服务等场景。
简而言之; 在IEnumerable
和IQueryable
之间做出选择,我选择不选择 – 选择使用IList
或List
。 如果我需要额外的过滤,那么:
上述就是C#学习教程:IEnumerable与IQueryable的业务逻辑或DAL返回类型分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
- 我将通过参数将其添加到现有API,并在我的数据层中进行过滤
- 我会接受超大数据回来,然后我需要在调用者处过滤掉
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/960673.html