Linq to sql Linq到SQL和Linq到对象查询是否相同?
如果我们抽象出DataContext,那么L2S和L2O查询是相同的吗 我已经有了一个工作原型来演示这一点,但它非常简单,不知道它是否能支持更高级的查询Linq to sql Linq到SQL和Linq到对象查询是否相同?,linq-to-sql,linq-to-objects,Linq To Sql,Linq To Objects,如果我们抽象出DataContext,那么L2S和L2O查询是相同的吗 我已经有了一个工作原型来演示这一点,但它非常简单,不知道它是否能支持更高级的查询 有人知道吗?不,他们不一样 LINQ to Objects查询对集合进行操作。该查询遍历集合,并针对集合中的项执行一系列方法(例如,等等) LINQ到SQL查询对集合进行操作。编译器将查询转换为表达式树,然后将该表达式树转换为SQL并传递给数据库 LINQtoSQL抱怨方法无法转换为SQL是很常见的,即使该方法在LINQtoObjects查询中
有人知道吗?不,他们不一样 LINQ to Objects查询对集合进行操作。该查询遍历集合,并针对集合中的项执行一系列方法(例如,等等) LINQ到SQL查询对集合进行操作。编译器将查询转换为表达式树,然后将该表达式树转换为SQL并传递给数据库 LINQtoSQL抱怨方法无法转换为SQL是很常见的,即使该方法在LINQtoObjects查询中非常有效。(在其他情况下,您可能看不到异常,但LINQ to对象和LINQ to SQL之间的查询结果可能略有不同。) 例如,LINQ to SQL将在这个简单查询中阻塞,而LINQ to对象则可以:
var query = from n in names
orderby n.LastName.TrimStart(',', ' ').ToUpper(),
n.FirstName.TrimStart(',', ' ').ToUpper()
select new { n.FirstName, n.LastName };
(通常可以绕过这些限制,但不能保证任何任意LINQ to Objects查询都能作为LINQ to SQL查询工作,这一事实告诉我它们是不同的!)查询语法是相同的。如果使用Enumerable.ToQuerable,则即使类型也是相同的。但也有一些区别:
- 某些查询只在L2O上工作,并会在L2S中导致运行时错误(例如,如果表达式树包含无法转换为SQL的函数,则在编译时无法检测到)
- 某些查询在L2和L2O上返回不同的结果(例如:Max([empty sequence])将在L2O中引发异常,但在L2S中返回null)
因此,最终,您必须针对数据库进行测试,但我认为L2O对于简单、快速的单元测试来说非常好。令人沮丧的是,所有的
实现本质上都是,泄漏的抽象——假设在LINQto对象中工作的东西在任何其他提供程序下仍能工作是不安全的。除了明显的函数映射之外,还有以下情况:
- LINQ to SQL不可能支持所有函数/重载-此处列出
- 加上它取决于实际的数据库服务器;Skip/Take等在SQL Server 2000上的工作方式与在2005+上的工作方式不同,而且并非所有此类翻译都在SQL Server 2000上工作
- EF不支持使用单个或表达式.Invoke(子表达式调用)或UDF
- Astoria支持不同的单/首选项使用;我记得它支持
Where(pred).Single()
-但不支持Single(pred)
(这是
因此,即使通过AsQueryable()
,您也不能在模拟数据库的单元测试中真正使用IEnumerable
——它根本不可靠。就我个人而言,出于这个原因,我将IQueryable
和Expression
远离存储库接口-请参见。当然可以,但正如我所说的,如果我们提取出数据上下文,那么您在这两者上使用的底层LINQ查询是相同的?看看我的意思的一个例子!谢谢,这就是我想知道的。虽然看起来大多数情况都可以,但如果是这样的话,我不能冒险推荐这种方法。哇。我不是唯一一个尝试过将IEnumerable转换为AsQueryable的人,我有一种预感,这太好了,不可能是真的。但是我最近买了Charlie Calvert的Essential LINQ——他在mocking的附录中提供了这个链接——我觉得另一种方法(上面概述的方法)给了我们更多的力量。嗯。我想我会回到完全分开的模拟和L2S回购的道路上,这样至少我可以交换我的DAL。顺便说一句,我在你的博客上发表了一条评论,很有趣。