I am using within my code some EF LINQ expressions to keep complex queries over my model in one place:
public static IQueryable<User> ToCheck(this IQueryable<User> queryable, int age, bool valueToCheck = true)
{
return queryable.Where(ToBeReviewed(age, valueToCheck));
}
public static Expression<Func<User, bool>> ToCheck(int age, bool valueToCheck = true)
{
return au => au.Status == UserStatus.Inactive
|| au.Status == UserStatus.Active &&
au.Age.HasValue && au.Age.Value > age;
}
I am then able to use them in queries:
var globalQuery = db.Users.ToCheck(value);
And also in selects:
var func = EntityExtensions.ToCheck(value);
var q = db.Department.Select(d => new
{
OrdersTotal = d.Orders.Sum(o => o.Price),
ToCheck = d.Users.AsQueryable().Count(func),
})
What I am trying to achieve is to actually use the same expression/function within a select, to evaluate it for each row.
var usersQuery = query.Select(au => new {
Id = au.Id,
Email = au.Email,
Status = au.Status.ToString(),
ToBeChecked = ???, // USE FUNCTION HERE
CreationTime = au.CreationTime,
LastLoginTime = au.LastLoginTime,
});
I am pretty that threre would be a way using plain EF capabilities or LINQKit, but can't find it.
Answering my own question :)
As pointed by @ivan-stoev, the use of Linqkit was the solution:
var globalQueryfilter = db.Users.AsExpandable.Where(au => au.Department == "hq");
var func = EntityExtensions.ToCheck(value);
var usersQuery = globalQueryfilter.Select(au => new
{
Id = au.Id,
Email = au.Email,
Status = au.Status.ToString(),
ToBeChecked = func.Invoke(au),
CreationTime = au.CreationTime,
LastLoginTime = au.LastLoginTime,
});
return appUsersQuery;
It's required to use the AsExpandable extension method from Linqkit along with Invoke with the function in the select method.