我有一个如此定义的界面:
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
属性?
答案 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);
}
......这完全符合要求。