【发布时间】:2012-02-17 01:41:56
【问题描述】:
我的存储库中有这个通用方法:
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 是 Int 类型:
someRepository.GetFirstOrDefault(m => m.myprop == someValue, m => m.Id, true);
像这样,其中 Name 是字符串类型:
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 子句应该如何声明?
【问题讨论】:
-
哪个属性是 DateTime 类型的?
-
您的方法名称有些混乱。您实际上是在执行 Min/Max 函数,但重载了另一种方法的名称,该方法执行的操作完全不同。我会小心的。
-
@ArsenMkrt:我的所有模型都派生自一个基础模型,该基础模型具有 DateCreated 类型的 DateTime 属性。
-
@JeffMercado 你能详细说明一下吗?你说的听起来很有趣,但我不确定我还重载了哪些其他函数?
-
当我看到
FirstOrDefault()方法时,我期望它返回集合中的第一项,或者如果它为空则返回类型的默认值。这是标准的 LINQ 方法。在这里,您定义了一个名称相似的方法,它做的事情完全不同,因此造成了混乱。该实现是通常用于在集合中查找最小值或最大值的项目的模式。我会将此方法命名为其他名称。一些这样做的库将其称为MinBy()或MaxBy()。我建议将其命名为MinMaxByOrDefault()或类似的名称。
标签: linq lambda sql-order-by