6

如果我们抽象出 DataContext,那么 L2S 和 L2O 查询是否相同?

我已经有一个可以证明这一点的工作原型,但它非常简单,想知道它是否能支持更高级的查询。

有人知道吗?

4

3 回答 3

10

不,他们不一样。

LINQ to Objects 查询对IEnumerable<T>集合进行操作。查询遍历集合并针对集合中的项目执行一系列方法(例如,ContainsWhere)。

LINQ to SQL 查询对IQueryable<T>集合进行操作。编译器将查询转换为表达式树,然后将该表达式树转换为 SQL 并传递给数据库。

LINQ to SQL 抱怨无法将方法转换为 SQL 是很常见的,即使该方法在 LINQ to Objects 查询中完美运行。(在其他情况下,您可能看不到异常,但查询结果在 LINQ to Objects 和 LINQ to SQL 之间可能略有不同。)

例如,LINQ to SQL 会阻塞这个简单的查询,而 LINQ to Objects 会很好:

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 查询工作这一事实告诉我,它们并不相同!)

于 2009-06-27T10:09:39.320 回答
6

令人沮丧IQueryably<T>的是,所有的实现本质上都是有漏洞的抽象——假设在 LINQ-to-Objects 中工作的东西在任何其他提供者下仍然可以工作是不安全的。除了明显的函数映射之外,还有以下内容:

  • LINQ-to-SQL 不可能支持所有函数/重载 - 此处列出数据类型和函数 (LINQ to SQL)
  • 加上它取决于实际的数据库服务器;Skip/Take 等在 SQL Server 2000 上的工作方式与 2005+ 不同,并且并非所有此类翻译都适用于 SQL Server 2000
  • EF 不支持 Single 或 Expression.Invoke(子表达式调用)或 UDF 使用
  • Astoria 支持Single/First 的不同使用;我记得它支持Where(pred).Single()- 但不支持Single(pred)(这是LINQ-to-SQL 的首选用法

所以你不能真正使用IEnumerable<T>模拟数据库的单元测试,即使通过AsQueryable()- 它根本不健壮。就个人而言,出于这个原因,我IQueryable<T>远离Expression存储库接口 - 请参阅Pragmatic LINQ

于 2009-06-27T10:41:54.590 回答
5

查询语法相同。如果你使用 Enumerable.ToQuerable,即使类型是一样的。但是有一些区别:

  • 某些查询仅适用于 L2O,并会导致 L2S 中的运行时错误(例如,如果表达式树包含无法转换为 SQL 的函数。这在编译时无法检测到)
  • 一些查询在 L2S 和 L2O 上返回不同的结果(例如:Max([empty sequence]) 将在 L2O 中抛出异常但在 L2S 中返回 null)

所以最后,你必须对数据库进行测试才能确定,但​​我认为 L2O 非常适合简单、快速的单元测试。

于 2009-06-27T10:35:01.607 回答