I want to define a Func<ProductItemVendor, bool>
filter expression named CompareProductItemVendorIds
, which can be used throughout my application, mostly within Entity Framework/LINQ queries.
I've learned that in order to be able to use this filter in a LINQ query, I must declare it as Expression<Func<>>
instead of just Func<>
. I understand the reason for this, and it's easy for me to do this.
But I'm having the following problems using that expression in my queries.
First, code such as:
ProductItem.ProductItemVendors.FirstOrDefault(CompareProductItemVendorIds)
Note: ProductItem
is a database entity, and its ProductItemVendors
property is a navigation collection.
Produces the error:
`Instance argument: cannot convert from 'System.Collections.Generic.ICollection' to 'System.Linq.IQueryable'
And second, code such as:
var results = from v in Repository.Query<ProductItemVendor>()
where CompareProductItemVendorIds(v)
select v;
Produces the error:
'CompareProductItemVendorIds' is a 'variable' but is used like a 'method'
So I have my nice shiny new Expression<Func<>>
. How can I use it in my LINQ queries?
ProductItem
is already an Entity
, so you can't use your Expression, you need to use Compile() to get the Func<>
from your Expression<Func<>>
since ProductItemVendors is no longer an IQueryable
ProductItem.ProductItemVendors.FirstOrDefault(CompareProductItemVendorIds.Compile())
You would have to use your Expression on the ProductItemVendorsContext like this:
var item = Context.ProductItemVendors.FirstOrDefault(CompareProductItemVendorIds);
You cant use an Expression inside query syntax, you need to use method sytanx
var results = from v in Repository.Query<ProductItemVendor>()
.Where(CompareProductItemVendorIds)
select v;
I don't think composing expressions like that is supported by default.
You could try LINQKit
Here's an example from the LINQKit page; one Expression<Func<>>
inside another:
Call Invoke to call the inner expression Call Expand on the final result. For example:
Expression<Func<Purchase,bool>> criteria1 = p => p.Price > 1000; Expression<Func<Purchase,bool>> criteria2 = p => criteria1.Invoke (p) || p.Description.Contains ("a"); Console.WriteLine (criteria2.Expand().ToString());
(Invoke and Expand are extension methods in LINQKit.) Here's the output:
p => ((p.Price > 1000) || p.Description.Contains("a"))
Notice that we have a nice clean expression: the call to Invoke has been stripped away.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With