The query:
List<int> companyIds = null;
(from car in context.GetTable<Car>()
where companyIds == null || companyIds.Contains(car.companyID)
select car)
.ToList();
The result:
at System.Linq.Enumerable.OfType[TResult](IEnumerable source) at System.Data.Linq.SqlClient.QueryConverter.VisitContains(Expression sequence, Expression value) at System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node) at 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.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(Expression node) at System.Data.Linq.SqlClient.SqlProvider.BuildQuery(Expression query, SqlNodeAnnotations annotations) at System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(Expression query) at System.Data.Linq.DataQuery
1.System.Collections.Generic.IEnumerable<T>.GetEnumerator() at System.Collections.Generic.List
1..ctor(IEnumerable1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable
1 source) at EVaultSDK.Services.CompanyService.Get...
If I add ToList
context.GetTable<Car>().ToList()
It works
I think the reason is you are using LINQ to SQL, your query needs to be translated into SQL and you get the exception while this translation happens. The Contains
is translated into IN
operator in SQL. But since the list is null I think the LINQ to SQL provider throws an exception.
This is the reason why you don't get the exception when you add ToList
after GetTable<Car>()
, this causes you to fetch and load all Cars
in memory, therefore the query runs on memory so don't need to be translated to SQL and the short-circuiting works as expected.
Normally if you call Contains
on a null list, you should get NullReferenceException
but you are getting ArgumentNullException
. So you should check stack trace and if it's the case, don't use a null list in your query.
Edit: The stack trace you posted confirms my assumption. Somewhere along the road OfType
method is called on the list and it causes the exception.
You already got a good answer on why you're getting the error - not everything in C# translates nicely to SQL, and you often don't find out until runtime.
Just in case a future visitor hits this question looking for a workaround, I'd suggest using the fact that you can build a query up and it won't retrieve any data until you call ToList()
(or Single()
, etc...):
List<int> companyIds = null;
var query = context.GetTable<Car>();
if (companyIds != null)
query = query.Where(car => companyIds.Contains(car.companyID));
var result = query.ToList();
Try this. It will return CompanyIds is null or contain car.CompanyID
return (from car in context.GetTable<Car>()
where companyIds == null || (companyIds != null && companyIds.Contains(car.companyID))
select car)
.ToList();
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.