使用OrderBy的存储库
我正在尝试创建一个存储库类,其中包含一个基于“sort”参数对结果进行排序的方法。 我需要将它作为参数传递,因为我试图非常严格,我的存储库不返回IQueryable并且只返回List。 问题是我不知道如何制作它以满足以下要求:
- 允许多列。
- 强烈键入返回的实体(没有列作为参数的列)。
- 能够将特定列设置为降序。
这是否可能,或者存储库允许返回订购是否无用? 存储库是否应该只能执行CRUD操作? 也许返回IQueryable是最好的选择?
也许你需要这样的东西:
public class Ordering { private readonly Func, IOrderedQueryable > transform; private Ordering(Func, IOrderedQueryable > transform) { this.transform = transform; } public static Ordering Create (Expression> primary) { return new Ordering(query => query.OrderBy(primary)); } public Ordering ThenBy(Expression> secondary) { return new Ordering(query => transform(query).ThenBy(secondary)); } // And more for the descending methods... internal IOrderedQueryable Apply(IQueryable query) { return transform(query); } }
然后,客户端可以创建要传递到存储库的Ordering
,并且存储库可以使用IQueryable
调用Apply
。 那有意义吗?
样品(略显傻)使用:
var ordering = Ordering.Create(fi => fi.Length) .ThenBy(fi => fi.Name);
这是有争议的,但我认为您的存储库应该只返回数据。 让您的消费类担心集合的顺序。
这背后的思考过程非常简单,消费类无论如何都会决定订单。 因此,他们可以将其传递给您的存储库中的手工制作的orderby生成器并让它完成工作,或者他们可以只使用linq并从存储库中订购它们返回的集合。 我认为后一个选项更容易实现,更不容易出错,并且在阅读代码时会更有意义,但我再一次认为我的观点是有争议的。
我认为直接返回IQueryable
通常是最好的选择。
例如,假设您有一个查询数据库以返回特定表或视图的方法。 如果存储库的客户端只需要前10条记录,并且具有您不期望的自定义条件和排序,则可以通过返回IQueryable
来允许此操作。 客户端只需要添加.Where(...).OrderBy(...).Take(10);
使用IQueryable
,跨数据层的调用将自动适应,并且只能拉出10条记录。 如果您返回List,则数据库查询将提取每条记录,然后过滤将需要在您的应用程序中进行。
这增加了巨大的处理/网络/等开销,没有真正的原因。