Linq、lambda表达式和OrderBy

Linq、lambda表达式和OrderBy,linq,lambda,sql-order-by,Linq,Lambda,Sql Order By,我的存储库中有以下通用方法: public T GetFirstOrDefault(Expression<Func<T, bool>> where, Expression<Func<T, object>> keySelector, bool ascending) { if (ascending) { return dbset.Where(where).OrderBy(keySelector).FirstOrDefau

我的存储库中有以下通用方法:

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>();
    }
}
像这样,其中Id是Int类型:

someRepository.GetFirstOrDefault(m => m.myprop == someValue, m => m.Id, true);
如下所示,其中名称为string类型:

someRepository.GetFirstOrDefault(m => m.myprop == someValue, m => m.Name, true)
但是,当我使用它时,它会给我以下错误:

无法将类型“System.DateTime”强制转换为类型“System.Object”。LINQ to Entities仅支持转换实体数据模型基元类型。

在做了一些研究之后,我发现可能我必须使用类型为
Expression
或类似的键选择器,这就是我感到困惑的地方。如果我这样声明我的方法,我不确定TKey应该来自哪里:

public T GetFirstOrDefault(Expression<Func<T, bool>> where, Expression<Func<TSource, TKey>> keySelector, bool ascending) { }
public T GetFirstOrDefault(表达式where、表达式keySelector、bool升序){

我走对了吗?我的OrderBy子句应该如何声明?

这个方法似乎是泛型类的一部分,类型参数
T
就是来自泛型类。如果仅此方法需要另一个类型参数,则必须使该方法本身为泛型:

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

(请注意,您当然不希望在第一个lambda中指定
=
,而是希望
=
。幸运的是,您的代码甚至不会编译。)

哪个属性的类型是DateTime?您的方法名有点混乱。实际上,您正在执行一个Min/Max函数,但是重载了另一种方法的名称,而这种方法的功能完全不同。我会小心的。@ArsenMkrt:我所有的模型都是从一个基本模型派生的,它有一个DateCreated属性,类型是DateTime。@JeffMercado你能详细说明一下吗?你说的话听起来很有趣,但我不确定我正在重载什么函数?当我看到方法
FirstOrDefault()
时,我希望它返回集合中的第一项,或者返回类型的默认值(如果它为空)。这是一种标准的LINQ方法。在这里,您定义了一个名称类似的方法,该方法做了一些完全不同的事情,因此存在混淆。实现是通常用于查找集合中最小或最大项的模式。我想把这个方法命名为其他方法。一些这样做的库调用它
MinBy()
MaxBy()
。我建议将其命名为
MinMaxByOrDefault()
或类似的名称。感谢您的详细解释!我想我已经试过了,但它不起作用,但我一定做了一些不同的事情,因为现在它起作用了。
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)