I'm trying to implement a type of eager loading functionality in a repository by passing in expressions for child objects needing hydration.
Candidate Get(int candidateId, params Expression<Func<Candidate, object>>[] includes);
So my services can call with something like this:
candidateRepository.Get(1, p => p.Notes, p => p.Profile, p => p.Application);
Where Notes, Profile, and Application are all properties of Candidate. Something like this:
public class Candidate
{
public string Name { get; set; }
public IList<CandidateNote> Notes { get; set; }
public Profile Profile { get; set; }
public Application Application { get; set; }
}
So, inside the repository I need to determine if a property was passed into the expression params to actually try hydrating it. But I'm not seeing a elegant way to achieve this.
public Candidate Get(int candidateId, params Func<Candidate, object>[] includes)
{
...
if (candidate.Notes property was specified?)
{
candidate.Notes = this.candidateNoteRepository.List(candidateId);
}
return candidate;
}
It looks like I can get the property name from the expression via (includes[0].Body as MemberExpression).Member.Name, but it seems there should be an easier way. Plus I'm not a fan of string comparison. I really wouldn't want to do it like this unless I have to:
if (includes[0].Body as MemberExpression).Member.Name == "Notes")
{
It seems like it should be something very simple like
if (includes[0].Is(candidate.Notes) or includes[0](candidate.Notes).Match())
{
Incase it comes up, I'd very much like to keep includes as an array of Expressions because although I'm working with ADO.NET today, we're planning to go the way of Entity Framework eventually and these expressions will work very nicely with the Include methods.
return this.Filter(m => m.Candidates.CandiateId == candidateId)
.Include(includes[0])
MemberInfoobject from theMemberExpressionexpression, rather than trying to hard code all of thoseifstatements for all of the properties.