is it possible to dynamically generate such a predicate using LambdaExpressions
?
Expression> predicate = t =>
t
I would recommend using nein-linq to combine, build and compose predicates (and many other expression puzzles), or LinqKit
Both support Entity Framework
For example, using nein-linq
Given:
public static class TestExpressions
{
[InjectLambda]
public static bool IsTestDateEarlierThan(this Test test, DateTime? dateTime, int numberOfDays)
{
return dateTime > test.TestDate.AddDays(numberOfDays);
}
public static Expression> IsTestDateEarlierThan()
{
return (test, dateTime, numberOfDays) => dateTime > DbFunctions.AddDays(test.TestDate, numberOfDays);
}
// Simple caching...
private static readonly Func _hasAnyLevelDateAfterTestDays = HasAnyLevelDateAfterTestDays().Compile();
[InjectLambda]
public static bool HasAnyLevelDateAfterTestDays(this Test test, int numberOfDays)
{
return _hasAnyLevelDateAfterTestDays(test, numberOfDays);
}
public static Expression> HasAnyLevelDateAfterTestDays()
{
return (test, numberOfDays) => test.Levels.Any(l => l.LevelDetails.Any(ld => test.IsTestDateEarlierThan(ld.LevelDate, numberOfDays)));
}
}
When:
var testList = new List
{
new Test {
Levels = new List {
new Level {
LevelDetails = new List {
new LevelDetail {
LevelDate = DateTime.Today
}
}
}
},
// Not matched
TestDate = DateTime.Today
},
new Test {
Levels = new List {
new Level {
LevelDetails = new List {
new LevelDetail {
LevelDate = DateTime.Today
}
}
}
},
// Not matched
TestDate = DateTime.Today.AddDays(-1)
},
new Test {
Levels = new List {
new Level {
LevelDetails = new List {
new LevelDetail {
LevelDate = DateTime.Today
}
}
}
},
// Matched
TestDate = DateTime.Today.AddDays(-2)
}
};
Then:
var testQuery = testList.AsQueryable();
// Alternative one
var result1 = testQuery
.ToInjectable() // Don't forget!!
.Where(test => test.Levels.Any(l => l.LevelDetails.Any(ld => test.IsTestDateEarlierThan(ld.LevelDate, 1))))
.ToList();
// Alternative two: You get the point :)
var result2 = testQuery
.ToInjectable() // Don't forget!!
.Where(test => test.HasAnyLevelDateAfterTestDays(1))
.ToList();