Linq for objects - reusing predicates with navigation properties?
I'm trying to find a way to reuse predicates to filter objects in EF 6.1.3. I am facing the problem of filtering related properties using "Where".
eg. if i have this interfaceIValidFromTo
public interface IValidFromTo
{
DateTime StartDate { get; set;}
DateTime EndDate { get; set; }
}
and a function that returns a predicate for Where
:
public class Extensions
{
public static Expression<Func<T, bool>> Current<T>()
where T : IValidFromTo
{
var currentDate = DateTime.Now;
return x => x.StartDate <= currentDate && x.EndDate >= currentDate;
}
}
See http://www.albahari.com/nutshell/predicatebuilder.aspx for background.
When applied directly to a DbSet, this method works.
var query = ctx.Items.Where(Extensions.Current<Item>()); // compiles
But how do you make it work for a more complex query about navigation properties?
eg. if i have DbSet<Person>
with a set Item
:
public class Person
{
...
public virtual ICollection<Item> Items { get; set; }
}
and I want to project it into an object containing the person's name, and only the current one Items
, I end up with some pretty cluttered code:
var relationQuery = ctx.People.Select(x => new
{ Name = x.Name,
CurrentItems = x.Items.AsQueryable().Where(Extensions.Current<Item>())
});
I wonder if this code can be improved, for example? to write something like
CurrentItems = x.Items.Current() // quasi an extension method on `ICollection<Item>`?
(writing the extension method ICollection<IValidFromTo>
doesn't work because EFf doesn't recognize this method and doesn't throw an error)
UPDATE
This seems to be achieved with Join
(suppose each Person
can only have one valid element):
var isCurrent= x => <<some condition on x>>;
...
var validItems = ctx.Items.Where(isCurrent);
var peopleWithCurrentItems = from person in ctx.Persons
join item in validItems on person.Id equals item.Owner.Id
select new { Person = person, Item = item };
If there can be several valid Item
for Person
, then
var grouped = peopleWithValid.GroupBy(x => x.Person);
However, this version of the query excludes people without a match Items
.
source to share
No one has answered this question yet
See similar questions:
or similar: