Lambda expression for querying an array of KeyValuePairs using Expression<Func<T, bool>>
I have an array of KeyValuePairs like this:
KeyValuePair<long,int>[] orderItems;
The 'long' component of this KeyValuePair corresponds to an Id (primary key) value on a database table.
Using the Entity Framework, I have defined a repository which provides the following method on its interface:
IEnumerabl开发者_如何学编程e<T> GetMany(Expression<Func<T, bool>> where);
The above repository method allows me to query the database using lambda expressions. For example, if I want to query the database for all rows where the 'Category' column equals 'Cameras' I can say this:
var results = repository.GetMany(a => a.Category.Contains("Cameras")).ToList();
What I want to query for is all rows where the Id (primary key) is equal to the Key value from any element of the array of KeyValuePairs. So if the list of KeyValuePairs is a list of product Ids and their quantities , I just want to query the database for all products whose Id is in my array.
Can anyone venture an appropriate lambda expression?
**EDIT TO ORIGINAL
The suggestion to use:
var results = repository.GetMany(a => keys.Any(x => x == a.Id)).ToList();
is a good one and will work if I first create an array of the keys from the KeyValuePair array. So something like this:
long[] pids = new long[orderItems.Length];
for (int i = 0; i < orderItems.Length; i++ )
{
pids[0] = orderItems[i].Key;
}
var products = productRepository.GetMany(a => pids.Any(x => x == a.Id)).ToList();
This shows that the 'Any' clause is supported by EF. I still can't get this to work without using the array of longs though. Kudos to anyone clever enough to give a solution that doesn't require me to extract the 'key' value from the KeyValuePair into an array first.
If I use the keys.Any I get the following exception:
"Unable to create a constant value of type 'System.Collections.Generic.IEnumerable`1'. Only primitive types (for instance Int32, String and Guid) are supported in this context"
Try this:
var keys = orderItems.Select(x => x.Key).ToList();
var results = repository.GetMany(a => keys.Any(x => x == a.Id))
.ToList();
it's hard to use the GetMany-Method while having the EF do it's work with the Database in this case. But you should have a query-Object named after your entities - I take here Categories (as a queryable object of a Type with an field/property Id) as a example. Then you can do:
var query = context.Categories;
foreach(var pair in orderedItems)
query = query.Union(context.Where(categorie => categorie.Id = pair.Key));
and finally using the query:
var results = query.ToList();
PS: to use this with your repository pattern you can just expose this queryable-Collection as IQueryable within your repository interface (or make a inherited interface from your generic repository for example ICategoryRepository)
精彩评论