c# - 为什么这种短路在 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.List
1..ctor(IEnumerable1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable
1 源)在 EVaultSDK.Services.CompanyService.Get...
如果我添加 ToList
context.GetTable<Car>().ToList()
有用
解决方案
我认为原因是您使用的是 LINQ to SQL,您的查询需要翻译成 SQL,并且在发生这种翻译时您会遇到异常。Contains
被翻译成SQL 中的IN
运算符。但由于列表为空,我认为 LINQ to SQL 提供程序会引发异常。
这就是为什么在添加ToList
after时不会出现异常的GetTable<Car>()
原因,这会导致您在内存中获取并加载所有Cars
内容,因此查询在内存上运行,因此不需要转换为 SQL 并且短路工作正如预期的那样。
通常,如果你调用Contains
一个空列表,你应该得到NullReferenceException
,但你得到的是ArgumentNullException
. 因此,您应该检查堆栈跟踪,如果是这种情况,请不要在查询中使用空列表。
编辑:您发布的堆栈跟踪证实了我的假设。沿路的某个地方OfType
在列表上调用方法,它会导致异常。
推荐阅读
- c++ - 在运行时将指针推送到向量 C++
- python - 有没有办法安排 Jupyter Notebook 每 2 分钟自动运行一次?
- apache-kafka - 从 HDF 3.4 通过 HDP 3.1 安装时如何获得适当的 Kafka 版本
- django - 在 Django 中测试成功发送邮件时发送邮件时出错
- unity3d - 为什么我的玩家角色在进入主菜单后无法更改
- r - 如何使用 R 中的下一个函数跳过 for 循环中的迭代
- macos - VTK Cmake VTK_BUILD_TESTING
- android - 通过单击主要活动中的按钮,我需要启用片段按钮
- ruby-on-rails - 如何在 Rails 5 环境中创建 Rails 6 应用程序
- mysql - 为什么 Sequel Pro 必须连接到 MAMP(或任何其他 mySQL 提供程序)