为什么这个短路不能在linq到sql查询中工作?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么这个短路不能在linq到sql查询中工作?相关的知识,希望对你有一定的参考价值。

查询:

List<int> companyIds = null;

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

结果:

System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node)中的System.Data.Linq.SqlClient.QueryConverter.VisitContains(表达式序列,表达式值)中的System.Linq.Enumerable.OnType.OnType。[TResult](IEnumerable source) System.Data.Linq.SqlClient.QueryConverter.VisitExpression(Expression exp)at System.Data.Linq.SqlClient.QueryConverter.VisitBinary(BinaryExpression b)at System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node)at System System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node)中System.Data.Linq.SqlClient.QueryConverter.VisitWhere(表达式序列,LambdaExpression谓词)的.Data.Linq.SqlClient.QueryConverter.VisitExpression(Expression exp)at at系统.Data.Linq.SqlClient.SqlProvider.System。 .Provider.IProvider.Execute(表达式查询)at EVaultSDK.Services.CompanyService.Get中的System.Data.Linq.DataQuery1.System.Collections.Generic.IEnumerable<T>.GetEnumerator() at System.Collections.Generic.List1..ctor(IEnumerable1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable1 source)...

如果我添加ToList

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

有用

答案

我认为原因是您正在使用LINQ to SQL,您的查询需要转换为SQL,并且在此转换发生时您会收到异常。 Contains在SQL中被翻译成IN运算符。但由于列表为null,我认为LINQ to SQL提供程序会抛出异常。

这就是为什么在ToList之后添加GetTable<Car>()时没有得到异常的原因,这会导致你在内存中获取并加载所有Cars,因此查询在内存上运行所以不需要转换为SQL和short - 电路按预期工作。

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

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

另一答案

你已经得到了一个很好的答案,为什么你得到错误 - 不是C#中的所有内容都很好地转换为SQL,并且你经常在运行时才发现。

为了防止未来的访问者遇到这个寻找解决方法的问题,我建议你使用这样一个事实:你可以建立一个查询,在你调用ToList()(或Single()等等)之前它不会检索任何数据:

List<int> companyIds = null;

var query = context.GetTable<Car>();
if (companyIds != null)
    query = query.Where(car => companyIds.Contains(car.companyID));

var result = query.ToList();
另一答案

试试这个。它将返回CompanyIds为null或包含car.CompanyID

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

以上是关于为什么这个短路不能在linq到sql查询中工作?的主要内容,如果未能解决你的问题,请参考以下文章

聚合函数不能在mysql中工作

C# 中的 LINQ to SQL 查询

为啥实体框架不能在 LINQ 语句中使用 ToString()?

为啥我的 XPath 查询(抓取 HTML 表)只能在 Firebug 中工作,而不能在我正在开发的应用程序中工作?

为啥这个 jQuery AJAX PUT 可以在 Chrome 中工作,但不能在 FF 中工作

为啥 VFP .NET OLEdb 提供程序不能在 64 位 Windows 中工作?