2012-02-16 46 views
1

我在我的仓库这个泛型方法:LINQ中,Lambda表达式和排序依据

public T GetFirstOrDefault(Expression<Func<T, bool>> where, Expression<Func<T, object>> keySelector, bool ascending) 
{ 
    if (ascending) 
    { 
     return dbset.Where(where).OrderBy(keySelector).FirstOrDefault<T>(); 
    } 
    else 
    { 
     return dbset.Where(where).OrderByDescending(keySelector).FirstOrDefault<T>(); 
    } 
} 

而且我希望能够像这样使用,其中dateCreated会DateTime类型:

someRepository.GetFirstOrDefault(m => m.myprop == someValue, m => m.DateCreated, true); 

像这样,其中ID为类型的诠释:

someRepository.GetFirstOrDefault(m => m.myprop == someValue, m => m.Id, true); 

像这样,其中名称是字符串类型:

someRepository.GetFirstOrDefault(m => m.myprop == someValue, m => m.Name, true) 

但是,它给了我,当我用它下面的错误:

无法转换类型“System.DateTime的”输入“System.Object的”。 LINQ to Entities仅支持投射实体数据模型基元类型。

之后做一些研究,我发现,也许我不得不使用Expression<Func<TSource, TKey>>型或类似的东西的一个KeySelector,而这正是我越来越糊涂了。如果我宣布我的方法是这样的,我不知道在哪里TKEY的应该是未来:

public T GetFirstOrDefault(Expression<Func<T, bool>> where, Expression<Func<TSource, TKey>> keySelector, bool ascending) { } 

我在正确的道路上?我的OrderBy子句应该如何声明?

+0

哪些属性是DateTime类型? – 2012-02-16 16:14:15

+0

你的方法名称有点混乱。你实际上在做一个Min/Max函数,但是重载另一种完全不同的方法的名字。我会小心的。 – 2012-02-16 16:20:59

+0

@ArsenMkrt:我所有的模型都是从一个DateCreated属性类型为DateTime的基础模型派生而来的。 – 2012-02-16 17:59:29

回答

3

看来这种方法是泛型类的一部分,这是类型参数T的来源。如果您需要其他类型的参数,只是这种方法,你必须做出方法本身一般:

public T GetFirstOrDefault<TKey>(
    Expression<Func<T, bool>> where, 
    Expression<Func<T, TKey>> keySelector, 
    bool ascending) 

然后,您可以调用它,并且明确指定参数:

someRepository.GetFirstOrDefault<string>(m => m.myprop == someValue, m => m.Name, true) 

或者让编译器推断它:

someRepository.GetFirstOrDefault(m => m.myprop == someValue, m => m.Name, true) 

(请注意,你肯定不希望在第一拉姆达分配=,你想==幸运的是,你的代码止跌。甚至不能编译。)

+0

感谢您的详细解释!我以为我曾尝试过这样做,但它没有奏效,但我一定做了一些与众不同的事情,因为现在它正在工作。 – 2012-02-16 19:30:10

+0

感谢您的好解决方案! – 2012-03-19 15:04:05