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?

+3


source to share


1 answer


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.

+2


source







All Articles