Entity Framework combines lambda expressions from different entities
I have 2 lambda expressions that are pretty much the same. One returns Expression<Func<Person, bool>>
and the other returns Expression<Func<Admission, bool>>
.
There is a direct connection between these two objects. A Person
can have many Admissions
.
The two expressions look like this:
Face :
public static Expression<Func<Person, bool>> SearchPerson(string searchTerm)
{
if(string.IsNullOrEmpty(searchTerm))
{
return p => true;
}
return p => p.Nhino.Contains(searchTerm) ||
p.Firstname.Contains(searchTerm) ||
p.Lastname.Contains(searchTerm) ||
p.Pfname.Contains(searchTerm);
}
Acceptance :
public static Expression<Func<Admission, bool>> SearchPerson(string searchTerm)
{
if(string.IsNullOrEmpty(searchTerm))
{
return a => true;
}
return a => a.Person.Nhino.Contains(searchTerm) ||
a.Person.Firstname.Contains(searchTerm) ||
a.Person.Lastname.Contains(searchTerm) ||
a.Person.Pfname.Contains(searchTerm);
}
These search expressions are widely used throughout the system.
Note that the operators are return
almost identical and if our client wants to add more search criteria to the list, I want to have this logic in one place and not update it for Admission
both Person
.
Is there a way to create an expression or similar that can be used in both a sentence People.Where()
and a sentence Admissions.Where()
(or even with respect to other parent / child relationships that want to search by the same criteria Person
), without duplicate code?
source to share
Provided that you have control over the design of these classes, you can implement an interface with a predicate function.
For example:
public interface ITestable
{
Func<string, bool> Predicate { get; }
}
public class Admission : ITestable
{
// ...other members...
public Person Person { get; }
public Expression<Func<string, bool>> Predicate =>
x => Person.Predicate(x);
}
public class Person : ITestable
{
// ...other members...
public Expression<Func<string, bool>> Predicate =>
x => string.IsNullOrEmpty(x) || FirstName.Contains(x) || LastName.Contains(x);
}
// The calling code:
IQueryable<ITestable> people =
source.Where(x => x.Predicate(searchTerm));
source to share