Is something like the following construct possible?
public IQueryable<T> AllWithFetch<TRelated>(IQueryable<T> existing, params Expression<Func<T, TRelated>>[] fetchExpressions)
{
return fetchExpressions.Aggregate(existing, (current, exp) => current.Fetch(exp));
}
Which could then be called like this…
var allDetails = this.preGrantDetailRepository
.AllWithFetch(this.preGrantDetailRepository.All, x => x.Case, x => x.CaseOwner)
Basically I am trying to include the addition of fetching strategies for NHibernate to our abstract repository, to enable us to specify these strategies from our logic layer without breaking the repository pattern. For example if we changed from NHibernate to another ORM we can then provide the same repository methods but implemented for that ORM.
The problem appears when I try to chain on more than one func in the param array.
So this works…
var allDetails = this.preGrantDetailRepository
.AllWithFetch(this.preGrantDetailRepository.All, x => x.Case)
But this fails with “the type arguments cannot be inferred from their usage” messge
var allDetails = this.preGrantDetailRepository
.AllWithFetch(this.preGrantDetailRepository.All, x => x.Case, x => x.CaseOwner)
I’m using .NET 3.5, Repository Pattern, Fluent NHibernate, SQL Server 2008
EDIT
I solved the problem in the with help from Porges answers below, so I have acepted it. The problem did come from an incorrect use of TRelated. Here is the working method in the repository…
public IQueryable<T> AllWithFetch<T>(IQueryable<T> existing, params Expression<Func<T, Entity>>[] fetchExpressions)
{
return fetchExpressions.Aggregate(existing, (current, exp) => current.Fetch(exp));
}
It is now AllWithFetch not TRelated and I am using the super class of the two entities (Case & CaseOwner) in the Func.
Thank you for your help guys
The problem is your
TRelated, this isn’t anything to do withparamsspecifically.Try this, for example:
The compiler will infer that
Tmust beint, but it cannot infer a good type forU(I’m not sure of the exact details, but it generally won’t look for a type higher up the inheritance chain).To get it to work, you need to specify the superclass; in this case,
object:So you’ll either need to specify a superclass yourself (which looks like it will be
objecthere), or just get rid of theTRelatedparameter.