首页 > 解决方案 > 为什么这种短路在 linq to sql 查询中不起作用?

问题描述

查询:

List<int> companyIds = null;

(from car in context.GetTable<Car>()
where companyIds == null || companyIds.Contains(car.companyID)
select car)
.ToList();

结果:

在 System.Linq.Enumerable.OfType[TResult](IEnumerable 源) 在 System.Data.Linq.SqlClient.QueryConverter.VisitContains(表达式序列,表达式值) 在 System.Data.Linq.SqlClient.QueryConverter.VisitInner(表达式节点)在 System.Data.Linq.SqlClient.QueryConverter.VisitExpression(Expression exp) 在 System.Data.Linq.SqlClient.QueryConverter.VisitBinary(BinaryExpression b) 在 System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression 节点) 在 System .Data.Linq.SqlClient.QueryConverter.VisitExpression(Expression exp) at System.Data.Linq.SqlClient.QueryConverter.VisitWhere(Expression sequence, LambdaExpression predicate) at System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node) at System.Data.Linq.SqlClient.QueryConverter.ConvertOuter(表达式节点)在 System.Data.Linq。System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(表达式查询)处 System.Data.Linq.DataQuery 处的 SqlClient.SqlProvider.BuildQuery(表达式查询,SqlNodeAnnotations 注释)1.System.Collections.Generic.IEnumerable<T>.GetEnumerator() at System.Collections.Generic.List1..ctor(IEnumerable 1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable1 源)在 EVaultSDK.Services.CompanyService.Get...

如果我添加 ToList

 context.GetTable<Car>().ToList()

有用

标签: c#linqlinq-to-sql

解决方案


我认为原因是您使用的是 LINQ to SQL,您的查询需要翻译成 SQL,并且在发生这种翻译时您会遇到异常。Contains被翻译成SQL 中的IN运算符。但由于列表为空,我认为 LINQ to SQL 提供程序会引发异常。

这就是为什么在添加ToListafter时不会出现异常的GetTable<Car>()原因,这会导致您在内存中获取并加载所有Cars内容,因此查询在内存上运行,因此不需要转换为 SQL 并且短路工作正如预期的那样。

通常,如果你调用Contains一个空列表,你应该得到NullReferenceException,但你得到的是ArgumentNullException. 因此,您应该检查堆栈跟踪,如果是这种情况,请不要在查询中使用空列表。

编辑:您发布的堆栈跟踪证实了我的假设。沿路的某个地方OfType在列表上调用方法,它会导致异常。


推荐阅读