是否有可能有一个Func的param数组

时间:2012-02-15 10:26:47

标签: c# fluent-nhibernate repository-pattern

是否可以使用以下构造?

  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)。

感谢您的帮助

2 个答案:

答案 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> 

代替(或任何界面)