Entity Framework combine lambda expressions from different entities

c# entity-framework entity-framework-6 expression lambda

Question

I have 2 lambda expressions that are virtually the same. One returns Expression<Func<Person, bool>> and the other returns Expression<Func<Admission, bool>>.

There is a direct relationship between these 2 entities. A Person can have many Admissions.

The two expressions look like this:

Person expression:

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);
}

Admission expression:

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 used extensively throughout the system.

Notice that the return statements are virtually 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 have to update it for both the Admission and Person expressions.

Is there a way to create an expression or similar that can be used in both the People.Where() clause and the Admissions.Where() clause (or even other Parent/Child relationships that want to search by the same Person criteria) without duplicating code?

1
3
5/12/2017 4:53:38 AM

Popular Answer

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));
0
5/12/2017 3:54:18 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow