如何强制EF LINQ查询生成不执行 [英] How to force EF LINQ query generation without execution

查看:152
本文介绍了如何强制EF LINQ查询生成不执行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个很好的解耦应用和依赖注入的应用程序,使用实体框架4.1 codeFirst通过一个存储库模式,揭露IQueryable的。这是很容易测试库客户端时嘲笑底层数据存储,但某一类错误的是不被抓住:

I have a nicely decoupled app and dependency-injected app that uses Entity Framework 4.1 CodeFirst to expose IQueryable through a repository pattern. It's easy enough to mock the underlying datastore when testing the repository clients, however a certain class of bug is not being caught:

这个仓库的客户可以自由地层自己的LINQ predicates,连接,等上什么样的信息库返回顶部:

The repository clients are free to layer their own LINQ predicates, joins, etc on top of what the repository returns:

{
     _myRepository.FindAll().Where( x => x.Id == 3 && SomeMethod(x.Name) == "Hello" );
}

这类型的查询会在一个单元测试,嘲笑_myRepository成功,因为模拟返回一个在内存中的集合实体和LINQ到对象是高兴地调用方法的someMethod。这将无法针对真正的数据存储,因为someMethod的不翻译在LINQ到实体为SQL。

This kind of query will succeed in a unit test that mocks _myRepository, because mock returns an in-memory collection of entities and LINQ-to-Objects is happy to call the method "SomeMethod". It will fail against the real data-store because "SomeMethod" does not translate to SQL in LINQ-to-Entities.

我试图想出一个办法,我既可以模拟数据集,并导致实际EF查询供应商产生(但不执行)的SQL。为什么?因为测试应该是快,我不想让他们打一个真正的数据库,如果在所有可能的。生成SQL将刷新出翻译问题是这样的。

I'm trying to figure out a way that I can both mock the dataset and cause the real EF query provider to generate (but not execute) the SQL. Why? Because the tests are supposed to be fast and I don't want them hitting a real database if at all possible. Generating the SQL will flush out translation issues like this.

到目前为止,我一直无法弄清楚如何做到这一点,因为在我的单元测试,我最终没有在查询时被物化的控制权。我想我需要可以提供我自己的版本的IQueryable和各种LINQ可查询扩展方法或试图通过提供机制挂钩的(使用示例从几年前,做缓存/跟踪供应商。)这两个这些看起来很多工作。就如何实现这一目标的任何想法?

So far, I have not been able to figure out how to do this, because in my unit tests, I am ultimately not in control of when the query gets materialized. I'm thinking I need to either provide my own version of IQueryable and the various LINQ Queryable extension methods or try and hook in via the provider mechanism (using the sample from a couple of years ago that does Caching/Tracing providers.) Both of these seem like a lot of work. Any ideas on how to achieve this?

推荐答案

没有就没有办法做到这一点 - 除非你要建立自己的供应商这又是解决不了问题,因为你必须测试真正的提供者不自定义实现,不会在实际code中使用。我讨论过<一个href="http://stackoverflow.com/questions/5625746/generic-repository-with-ef-4-1-what-is-the-point/5626884#5626884">here和<一href="http://stackoverflow.com/questions/5609508/asp-net-mvc3-and-entity-framework-$c$c-first-architecture/5610685#5610685">here. <一href="http://stackoverflow.com/questions/5488313/organizationally-where-should-i-put-common-queries-when-using-entity-framework-c/5488947#5488947">One有关库本身的更多相关答案。

No there is no way to do that - unless you are going to build your own provider which in turn is not the solution because you must test the real provider not a custom implementation which will not be used in the real code. I discussed it here and here. One more related answer about repository itself.

只要你不能没有做数据库的映射和持久性测试数据库映射和持久性。有一些很奇怪的信念,测试应用程序就是写单元测试。这是不对的定义。测试应用程序是指编写测试和单元测试有很多的测试类型的只是一个,但他们不能检验一切。你需要将它们与其他类型的测试结合起来。正确的做法对于这种情况可以是不必每次运行,但可以安排在构建服务器集成测试。

Simply you can't test database mapping and persistence without doing database mapping and persistence. There is some very strange belief that testing application means writing unit tests. That is wrong definition. Testing application means writing tests and unit tests are just one of many test types but they can't test everything. You need to combine them with other types of tests. The correct approach for this scenario can be integration tests which doesn't have to run every time but can be scheduled on the build server.

这篇关于如何强制EF LINQ查询生成不执行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆