C#通用orderby

Ale*_*lex 5 linq generics expression entity-framework sql-order-by

在我的基础存储库类中

我编写了这个函数,以便从数据库中检索排序的数据集合。T 是在类级别定义的泛型

public abstract class RepositoryBase<T> 
        where T : class
Run Code Online (Sandbox Code Playgroud)

代码是这样的:

public IList<T> GetAll<TKey>(Expression<Func<T, bool>> whereCondition, Expression<Func<T, TKey>> sortCondition, bool sortDesc = false)
        {
            if (sortDesc)
                return this.ObjectSet.Where(whereCondition).OrderByDescending(sortCondition).ToList<T>();

            return this.ObjectSet.Where(whereCondition).OrderBy(sortCondition).ToList<T>() ;
        }
Run Code Online (Sandbox Code Playgroud)

我的目标是引入一个通用的排序参数,以便我可以这样调用函数:

repo.GetAll (model=>model.field>0, model=>model.sortableField, true)
Run Code Online (Sandbox Code Playgroud)

我的意思是我可以通过匿名函数直接指定排序字段,因此使用 Intellisense ......

不幸的是,这个函数不起作用,因为最后一行代码在编译时会产生错误。

我也试着打电话:

repo.GetAll<Model> (model=>model.field>0, model=>model.sortableField, true)
Run Code Online (Sandbox Code Playgroud)

但这不起作用。

我应该如何编写函数来满足我的目标?

我正在使用 EF 5、c#、.NET 4.5

Amy*_*y B 3

您正在使用ObjectSetwhich Implements IQueryable<T>。这是通过System.Linq.Queryable接受Expression<Func<参数的方法进行扩展的。使用这些Expression参数是正确的,因为您打算在数据库中执行,而不是在本地执行。

  • Func 是一个匿名委托,一个 .net 方法。
  • 表达式是一棵树,它可以编译成 Func,也可以翻译成 Sql 或其他东西。

您向我们展示了该方法的真正抽象用法,但没有实际使用该方法,也没有显示编译器错误。我怀疑您可能犯的错误是混淆了两种类型参数。

你说:

repo.GetAll<Model> (model=>model.field>0, model=>model.sortableField, true)
Run Code Online (Sandbox Code Playgroud)

但该方法的通用参数表示 sortableField 的类型。如果 sortableField 不是模型 - 这是错误的。

相反,你应该这样做:

Repository<Person> myRepo = new Repository<Person>();
myRepo.GetAll<DateTime>(p => p.Friends.Count() > 3, p => p.DateOfBirth, true);
Run Code Online (Sandbox Code Playgroud)

如果指定排序类型破坏了您预期的使用模式,请考虑使用 IOrderer 隐藏该键:将多类型 OrderBy 表达式存储为属性