Reputation: 31
Very often I have need for queries similar to this:
SELECT * FROM Customers
WHERE City IN ('Paris','London');
I have some list (most often strings). When list is small (like this in example), it is not such a problem, I can write something like this (C#):
Customers custs = this.DataWorkspace.ApplicationData.Customers;
var filteredcustomers = custs.Where(c=>c.City == "Paris" || c=>c.City == "London");
but if I have bigger list, it's a little clumsy. I've tried this (from some forum):
List<string> months = new List<string>() {"Jan", "Feb", "Mar"......"Dec"};
Customers custs = this.DataWorkspace.ApplicationData.Customers;
var filteredcustomers = custs.Where(c => months.Contains(c.City));
but I get run-time error:
"{System.NotSupportedException:
The expression value(System.Collections.Generic.List`1[System.String]).Contains([10007].City) is not supported. ..."
Upvotes: 2
Views: 588
Reputation: 31
First, thanks both @danielrozo and @sh1ng for answering the question. The thing is, both suggestions don't work at run-time, when at some point in code I try to .Execute() query or do foreach loop (when query actually executes), and I think that I finally figure out why:
this.DataWorkspace.ApplicationData.Customers;
this is EntitySet and I found out that it doesn't support full set of LINQ operators (it doesn't support 'Contains'). It supports only restricted se of LINQ operators. If list is for example:
List<string> cities = new List<string>() {"Paris", "London", "Berlin", "Moscow",.....};
and I modify 'custs' like this:
var custs = this.DataWorkspace.ApplicationData.Customers.GetQuery().Execute();
it returns IEnumerable object and we can use it to filter locally. IEnumerable supports full set of LINQ operators and now both suggestions works. E.g. from @danielrozo
var fi = from fcusts in custs where custs.Any(x => cities.Contains(x.City)) select fcusts;
Now, this also works:
var filteredcustomers = custs.Where(c => cities.Contains(c.City));
Also I can do sums (when needed):
decimal total = custs.Where(c => cities.Contains(c.City)).Sum(c => c.Points);
We need to be careful here, because .GetQuery().Execute() returns all records from server (in this case Customers), which can has impact on performance if we have a lot of records.
I hope this will help somebody.
Upvotes: 1
Reputation: 2973
Use array instead of List<>
var filteredcustomers = custs.Where(c => months.ToArray().Contains(c.City));
Upvotes: 0
Reputation: 1442
Try this:
var filteredCustomers = from fcusts in custs where custs.Any(x=>x.Contains<string>(x.City)) select fcusts;
This way you'll be calling Enumerable.Contains and not List.Contains.
Upvotes: 0