使用OrderBy的存储库

时间:2010-06-25 16:01:08

标签: c# asp.net-mvc linq

我正在尝试创建一个存储库类,其中包含一个基于“sort”参数对结果进行排序的方法。我需要将它作为参数传递,因为我试图非常严格,我的存储库不返回IQueryable并且只返回List。问题是我不知道如何制作它以满足以下要求:

  1. 允许多列。
  2. 对返回的实体进行强类型化(没有列作为参数的列)。
  3. 能够将特定列设置为降序。
  4. 这是否可能,或者存储库允许返回订购是否无用?存储库是否应该只能执行CRUD操作?也许返回IQueryable会是最好的选择吗?

3 个答案:

答案 0 :(得分:7)

也许你需要这样的东西:

public class Ordering<T>
{
    private readonly Func<IQueryable<T>, IOrderedQueryable<T>> transform;

    private Ordering(Func<IQueryable<T>, IOrderedQueryable<T>> transform)
    {
        this.transform = transform;
    }

    public static Ordering<T> Create<TKey>
        (Expression<Func<T, TKey>> primary)
    {
        return new Ordering<T>(query => query.OrderBy(primary));
    }

    public Ordering<T> ThenBy<TKey>(Expression<Func<T, TKey>> secondary)
    {
        return new Ordering<T>(query => transform(query).ThenBy(secondary));
    }

    // And more for the descending methods...

    internal IOrderedQueryable<T> Apply(IQueryable<T> query)
    {
        return transform(query);
    }
}

然后,客户端可以创建要传递到存储库的Ordering<T>,并且存储库可以使用Apply调用IQueryable<T>。这有意义吗?

样品(稍微傻)使用:

var ordering = Ordering<FileInfo>.Create(fi => fi.Length)
                                 .ThenBy(fi => fi.Name);

答案 1 :(得分:3)

这是有争议的,但我认为您的存储库应该只返回数据。让你的消费类担心集合的排序。

这背后的思考过程非常简单,消费类无论如何都要决定订单。因此,他们可以将其传递给您的存储库中的手工制作的orderby生成器并让它完成工作,或者他们可以只使用linq并从存储库中订购它们返回的集合。我认为后一个选项更容易实现,更不容易出错,并且在阅读代码时更有意义,但我再一次认为我的观点是有争议的。

答案 2 :(得分:2)

我认为直接返回IQueryable<T>通常是最佳选择。

例如,假设您有一个查询数据库以返回特定表或视图的方法。如果存储库的客户端只需要前10条记录,并且具有您不期望的自定义​​条件和排序,则可以通过返回IQueryable<T>来允许此操作。客户只需添加.Where(...).OrderBy(...).Take(10);

使用IQueryable<T>,跨数据层的调用将自动适应,并且只会拉出10条记录。如果您返回List,则数据库查询将提取每条记录,然后需要在您的应用程序中进行过滤。

这增加了巨大的处理/网络/等开销,没有任何正当理由。