通用扩展方法</t,>中的嵌套Func <t,object =“”>

时间:2014-12-13 14:55:16

标签: c# linq generics delegates extension-methods

我有一个如此定义的界面:

public interface IEntityUnitOfWork : IEntityModelUnitOfWork, IDisposable
{
    IQueryable<T> IncludeProperties<T>(IQueryable<T> theQueryable, params Func<T, object>[] toInclude)
        where T : class, new();
}

...这允许我编写这样的代码:

var foo = MyUnitOfWork.IncludeProperties(
    MyUnitOfWork.MyQueryable,
    p=>p.MyProperty1,
    p=>p.MyProperty2,
    ...
    p=>p.MyPropertyN);

对于实现有一些魔力,这很有效。但它似乎很尴尬。我想我应该能写出这种清洁剂,所以我可以使用这种格式:

var foo = MyUnitOfWork.Fetch(
    f=>f.MyQueryable,
    p=>p.MyProperty1,
    p=>p.MyProperty2,
    ...
    p=>p.MyPropertyN);

所以我写了一个像这样的扩展方法:

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 ;
}

这构建,并且Intellisense按照我的预期工作,但当然在实际尝试使用它时,它会失败并显示NullReferenceException。 {I}我假设queryable.Target是我试图引用的IQueryable<T>,似乎不是我想象的那样,而且我没有从我的Intellisense / Quickwatch选项中看到明显的其他选择

如何将q值设置为我想要在以下语句中引用的IQueryable<T> IEntityUnitOfWork属性?

1 个答案:

答案 0 :(得分:2)

好的,经过多次修补后,看起来我不想要函数的Target属性,而是Invoke()方法:

var q = queryable.Invoke(unitOfWork);

经过一些优化后,我看起来像这样:

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);
}

......这完全符合要求。