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