我的存储库中有这个通用方法:
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的类型为string:
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 :(得分: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)
(注意你肯定不希望在第一个lambda中赋值=
,你想要==
。幸运的是,你的代码甚至都不会编译。)