I am building a method that takes one or more criteria for querying a database with LINQ. I made this:
public ICollection<MyClass> FindAllBy(params Expression<Func<MyClass, bool>>[] criteria)
{
using (var ctx = new MyContext())
{
IQueryable<MyClass> result = ctx.MyClasses.AsNoTracking();
if (criteria != null && criteria.Length > 0)
{
foreach (var item in criteria)
{
result = result.Where(item);
}
}
return result.ToList();
}
}
This has the effect that if I look for a object with Id 1 and one with Id 2 I get nothing, as no row has both an Id of 1 and 2. So I need an OR clause. I found this page:
http://www.albahari.com/nutshell/predicatebuilder.aspx
Which has a PredicateBuilder class, which I used to make this:
public ICollection<PhotoFile> FindAllBy(params Expression<Func<PhotoFile, bool>>[] criteria)
{
using (var ctx = new CotanContext())
{
var predicate = PredicateBuilder.False<PhotoFile>();
if (criteria != null && criteria.Length > 0)
{
foreach (var item in criteria)
{
predicate = predicate.Or(item);
}
}
return ctx.PhotoFiles.Where(predicate).ToList();
}
}
My code differs slightly from the page in that I pass in an expression into the method, which I then pass into the Predicate.Or method.
The above method gives a The LINQ expression node type 'Invoke' is not supported in LINQ to Entities.
error. Which makes sense, as Entity Framework does not know how to translate this code into a valid query.
The solution on the linked site is to download their Nuget package or source code, which makes this code work. However, I don't really feel comfortable putting in several hundreds of lines of unknown and seemingly untested code for a single function, that in my opinion should have been built into LINQ ages ago by Microsoft. And the lead developer on my project has also in the past strongly advised against using unknown packages that aren't directly from Microsoft. I am working with sensitive information, so I would rather be safe than sorry.
So, my question: is there any way to get an OR function in LINQ without having to use an external Nuget package?