如何确定 LINQ 查询是 LINQ to SQL 还是 LINQ to Objects?

Pro*_*one 5 c# linq linq-to-sql

通常 LINQ to SQL 和 LINQ to Objects 之间的区别不是问题(我认为从一开始就将其作为问题是过早的优化),但是我如何确定发生了什么?

在编写代码时知道会很有用,但我担心有时只能在运行时确定。

Tim*_*ter 3

区分 Linq-To-Sql 和 Linq-To-Objects并不是微优化。后者要求在开始过滤之前将所有数据加载到内存中。当然,这可能是一个主要问题。

大多数 LINQ 方法都使用延迟执行,这意味着它只是构建查询但尚未执行(如SelectWhere)。很少有其他人执行查询并将结果具体化到内存中的集合中(例如ToLIstToArray)。如果您使用,AsEnumerable您也在使用Linq-To-Objects,并且不会为其后面的部分生成 SQL,这意味着数据必须加载到内存中(但仍使用延迟执行)。

因此,请考虑以下两个查询。第一个在数据库中选择和过滤:

var queryLondonCustomers = from cust in db.customers
                           where cust.City == "London"
                           select cust;
Run Code Online (Sandbox Code Playgroud)

而第二个选择全部并通过以下方式过滤Linq-To-Objects

var queryLondonCustomers = from cust in db.customers.AsEnumerable()
                           where cust.City == "London"
                           select cust;
Run Code Online (Sandbox Code Playgroud)

后者有一个优点:您可以使用任何 .NET 方法,因为它不需要转换为 SQL(例如!String.IsNullOrWhiteSpace(cust.City))。

如果您只是得到一个 的东西IEnumerable<T>,您无法确定它是否实际上是一个查询或已经是一个内存中的对象。由于-method的原因,即使 try-cast 也IQueryable<T>不会告诉您它实际上是什么。也许您可以尝试将其转换为集合类型。如果转换成功,您可以确定它已经实现,但否则它不会告诉您它是否正在使用or :AsQueryableLinq-To-SqlLinq-To-Objects

bool isMaterialized = queryLondonCustomers as ICollection<Customer> != null;
Run Code Online (Sandbox Code Playgroud)

相关:EF ICollection、List、IEnumerable、IQueryable