Home > Software engineering >  Pass where condition as parameter using LINQ expression query
Pass where condition as parameter using LINQ expression query

Time:01-05

Initially I have the following query in a function. This query is used in the join in another query, which I didn't add due to its size.

var latestGuestRegistration = from c in Context.Guest
                group c by c.PersonId
                into cc
                select new { PersonId = cc.Key, CreationTime = cc.Max(a => a.CreationTime) };

I would like to add a filter, however I could filter by name or email. So I would like to pass this filter as a function parameter.

I couldn't do this using C#'s inline SQL syntax, so I tried converting to LINQ:

var tmp = Context.GuestRegistrations
                .Where(filter) // Here I filter by email or name
                .GroupBy(x => x.PersonId)
                .Select(cc => new { PersonId = cc.Key, CreationTime = cc.Max(a => a.CreationTime) })
                .AsQueryable();

According to Rider, both implementations have the same data type, which is Queryable<{ID, CreationTime}>

// Joins above
 join lt in tmp on
                new { guestRegistration.PersonId, guestRegistration.CreationTime } equals
                new { lt.PersonId, lt.CreationTime }
// Joins below

When this join is executed using my LINQ, it seems that it already returns the data, while the original solution enters as a subquery. How can I add a filter to my original query?

In the end, I would like something more or less like this:

Expression<Func<GuestRegistration,bool>> wherePredicate = registration => registration.FullName = "Gabriel";

var latestGuestRegistration = from c in Context.GuestRegistrations
                where wherePredicate
                group c by c.PersonId
                into cc
                select new { PersonId = cc.Key, CreationTime = cc.Max(a => a.CreationTime) };

Solution

Thanks to everyone who responded and commented, below is a summary of the final code.

private IQueryable<...> GetSearch(Expression<Func<G, bool>> filter) {
    var filteredG= Context.G.Where(filter);
    var latestG = from c in filteredG
                group c by c.PersonId
                into cc
                select new { PersonId = cc.Key, CreationTime = cc.Max(a => a.CreationTime) };

    var bigQuery = from ... join latestG ...
}
    
GetSearch(x => x.Fullname == "Gabriel")

CodePudding user response:

Some expressions cannot be injected via Query syntax, but you can mix it with Method Chain syntax:

Expression<Func<GuestRegistration,bool>> wherePredicate = registration => registration.FullName = "Gabriel";

var guestRegistrations = Context.GuestRegistrations
     .Where(wherePredicate);

var latestGuestRegistration = 
    from c in guestRegistrations
    group c by c.PersonId
    into cc
    select new { PersonId = cc.Key, CreationTime = cc.Max(a => a.CreationTime) };
  • Related