是否可以使用以下构造?
public IQueryable<T> AllWithFetch<TRelated>(IQueryable<T> existing, params Expression<Func<T, TRelated>>[] fetchExpressions)
{
return fetchExpressions.Aggregate(existing, (current, exp) => current.Fetch(exp));
}
然后可以这样调用......
var allDetails = this.preGrantDetailRepository
.AllWithFetch(this.preGrantDetailRepository.All, x => x.Case, x => x.CaseOwner)
基本上我试图将NHibernate的提取策略添加到我们的抽象存储库中,以使我们能够从逻辑层指定这些策略而不破坏存储库模式。例如,如果我们从NHibernate更改为另一个ORM,那么我们可以为该ORM提供相同的存储库方法。
当我尝试链接param数组中的多个func时,会出现问题。
所以这有效......
var allDetails = this.preGrantDetailRepository
.AllWithFetch(this.preGrantDetailRepository.All, x => x.Case)
但是这种情况失败了,“无法从使用中推断出类型参数”的消息
var allDetails = this.preGrantDetailRepository
.AllWithFetch(this.preGrantDetailRepository.All, x => x.Case, x => x.CaseOwner)
我正在使用.NET 3.5,Repository Pattern,Fluent NHibernate,SQL Server 2008
修改
我在下面的Porges答案的帮助下解决了这个问题,所以我已经接受了它。问题确实来自于错误使用TRelated。这是存储库中的工作方法......
public IQueryable<T> AllWithFetch<T>(IQueryable<T> existing, params Expression<Func<T, Entity>>[] fetchExpressions)
{
return fetchExpressions.Aggregate(existing, (current, exp) => current.Fetch(exp));
}
现在AllWithFetch没有被TRelated,我在Func中使用了两个实体的超类(Case&amp; CaseOwner)。
感谢您的帮助
答案 0 :(得分:4)
问题在于您TRelated
,这与params
无关。
试试这个,例如:
void DoSomething<T,U>(Func<T,U> f, Func<T,U> f2)
{
}
void Main()
{
DoSomething((int x) => x + 1, (int x) => x + "");
}
编译器会推断T
必须是int
,但它无法推断出U
的良好类型(我不确定完全细节,但它通常不会寻找继承链上方的类型。)
要使其工作,您需要指定超类;在这种情况下,object
:
void Main()
{
DoSomething<int,object>((int x) => x + 1, (int x) => x + "");
}
所以你需要自己指定一个超类(看起来好像在这里object
),或者只是去除TRelated
参数。
答案 1 :(得分:2)
你应该将TRelated作为每个func的返回值。 .Case和.CaseOwner有相同的类型吗?如果不是,您可以使用
Func<T, object>
代替(或任何界面)