我有一个这样定义的接口(interface):
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
. queryable.Target
,我假设是 IQueryable<T>
我试图引用的,似乎不是我所假设的,而且我没有从我的 Intellisense/Quickwatch 选项中看到明显的其他选择。
如何设置 q
值为 IQueryable<T>
我的属性(property)IEntityUnitOfWork
我想在以下语句中引用?
最佳答案
好吧,经过更多的修改,看起来我不需要函数的 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);
}
...这完全符合预期。
关于c# - 通用扩展方法中的嵌套 Func<T, object>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27460132/