Nested Func <T, object> in a generic extension method
I have an interface defined like this:
public interface IEntityUnitOfWork : IEntityModelUnitOfWork, IDisposable
{
IQueryable<T> IncludeProperties<T>(IQueryable<T> theQueryable, params Func<T, object>[] toInclude)
where T : class, new();
}
... which allows me to write code like this:
var foo = MyUnitOfWork.IncludeProperties(
MyUnitOfWork.MyQueryable,
p=>p.MyProperty1,
p=>p.MyProperty2,
...
p=>p.MyPropertyN);
With some mojo to implement, this works pretty smoothly. But this seems inconvenient. I think I should have written this clean, so I can use a format like this:
var foo = MyUnitOfWork.Fetch(
f=>f.MyQueryable,
p=>p.MyProperty1,
p=>p.MyProperty2,
...
p=>p.MyPropertyN);
So, I wrote an extension method like this:
public static IQueryable<T> Fetch<T>(
this IEntityUnitOfWork unitOfWork,
Func<IEntityUnitOfWork, IQueryable<T>> queryable,
params Func<T, object>[] toInclude) where T:class, new()
{
var q = queryable.Target as IQueryable<T>;
foreach (var p in toInclude)
{
q = unitOfWork.IncludeProperties(q, new[] { p });
}
return q ;
}
This builds and Intellisense works as I expected, but of course when he actually tries to use it he fails with NullReferenceException
. queryable.Target
which I assumed would be IQueryable<T>
, which I was trying to link to does not seem to be what I assumed, and I do not see any obvious other choice from my Intellisense / Quickwatch options.
How do I set the value q
as a property IQueryable<T>
from mine IEntityUnitOfWork
that I want to reference in the following statements?
source to share
OK, after more intervention, it looks like I don't need the property of the Target
function, but the method Invoke()
:
var q = queryable.Invoke(unitOfWork);
after some optimization, i did it like this:
public static IQueryable<T> Fetch<T>(
this IEntityUnitOfWork unitOfWork,
Func<IEntityUnitOfWork, IQueryable<T>> queryable,
params Func<T, object>[] toInclude) where T : class, new()
{
var q = queryable.Invoke(unitOfWork);
return unitOfWork.IncludeProperties(q, toInclude);
}
... and it works exactly the way you want it to.
source to share