在存储库方法中键入推断

时间:2013-03-15 01:40:57

标签: c# asp.net-mvc entity-framework

我有一个RepositoryBase类,我为我的Entity Framework Context定义了基本的crud方法。我有这两个All()方法的重载:

public virtual IQueryable<T> All<TKey>(Expression<Func<T, bool>> predicate)
{
    return All().Where(predicate);
}

public virtual PagedResult<T> All<TKey>(int startRowIndex, int maximumRows,
    Expression<Func<T, TKey>> orderingKey, Expression<Func<T, bool>> predicate,
    bool sortDescending = false)
{
    var subset =  All().Where(predicate);

    IEnumerable<T> result = sortDescending
                                ? subset.OrderByDescending(orderingKey).Skip(startRowIndex).Take(maximumRows)
                                : subset.OrderBy(orderingKey).Skip(startRowIndex).Take(maximumRows);

    //More code ommited
}

第一种方法总是需要我明确指定实体类型,但第二种方法不需要。这是为什么?

示例,这不编译:

return All(s => s.LoanApplicationId == loanApplicationId)

相反,我必须这样称呼它:

return All<LoanApplication>(s => s.LoanApplicationId == loanApplicationId)

但是这可以编译:

return All(0,10, s => s.Name, s => s.LoanApplicationId == loanApplicationId, false)

1 个答案:

答案 0 :(得分:2)

TKey位于第二个参数列表中(通过Expression<Func<T, TKey>> orderingKey),而不是第一个参数列表。当你使用提供的参数(s => s.Name)使用它时,第二个成功地推断出类型。你不会在第一个版本中给自己那么奢侈,因此编译器会强制你通过显式提供type参数来填写细节。

从它的外观来看,无论如何你都不需要TKey,所以可能摆脱它(除非有比这个相对简单的实现更多的代码可见)。而且我认为这并不意味着您的示例调用认为它意味着什么。例如,TKey中的string可能是s.Name(无论{{1}}的类型是什么)。