Asp.net-Mvc
在控制器中進行 linq 查詢是一種好習慣嗎?
我對 MVC 模式不是很熟悉。你能告訴我以下三個控制器動作中哪一個更好嗎?謝謝 :)
(1) 有查詢:
public ActionResult List() { var query = repository.Query().Where(it => it.IsHandled).OrderBy(it => it.Id); // ... }(2) 服務中有查詢:
public ActionResult List() { var items = service.GetHandledItemsOrderById(); // ... }(3) 行動有序:
public ActionResult List() { var items = service.GetHandledItems().OrderBy(it => it.Id); // ... }如果我們選擇(1),那麼我們在控制器中的業務邏輯太多了?
如果我們選擇(2),可能會有很多服務方法,例如
GetXXXByYYY().如果我們選擇(3),為什麼我們封裝
Where(it => it.IsHandled)而不是
OrderBy(it => it.Id。有任何想法嗎?
這取決於。:)
我的意見:
我喜歡讓我的服務保持鬆散,以盡量減少重複程式碼。我也是管道和過濾器的粉絲。
這就是我會做的(並且會做的)。
服務
public ICollection<Item> GetHandledItems<TKey>(OrderingOptions<Item, TKey> orderingOptions) { return repository .Query() .WhereHandled() .WithOrdering(orderingOptions) .ToList(); }項目過濾器.cs
public static IQueryable<Item> WhereHandled(this IQueryable<Item> source) { return source.Where(it => it.IsHandled); } public static IOrderedQueryable<T> WithOrdering<T, TKey>( this IQueryable<T> source, OrderingOptions<T, TKey> orderingOptions) { return orderingOptions.SortDescending ? source.OrderByDescending(orderingOptions.OrderingKey) : source.OrderBy(orderingOptions.OrderingKey); }訂購選項.cs
public class OrderingOptions<T,TKey> { public OrderingOptions(Expression<Func<T,TKey>> orderingKey, bool sortDescending = false) { OrderingKey = orderingKey; SortDescending = sortDescending; } public Expression<Func<T,TKey>> OrderingKey { get; private set; } public bool SortDescending { get; private set; } }這樣,您可以在 Controller 中指定排序:
var items = service.GetHandledItems(new OrderingOptions(it => it.Id));以上與方案3的區別:
- 上面實現了返回控制器之前的序列。選項 3 沒有,這很危險(您最終可能會將查詢返回到 View 並破壞 MVC 模式)。
- 通用的“訂購”POCO,可以在任何地方使用並保持您的查詢乾燥。
- 服務變得愚蠢,並且只是儲存庫和控制器之間的緩解器(這就是它應該做的,IMO)。邏輯(例如過濾器)抽像到一個地方。
我確信意見可能會有所不同,但我已經學會了盡量在服務中保留盡可能多的業務邏輯。3是我的選擇。使用 1,您已經發現了問題。使用 2,您將在服務中引入顯示優先級。使用 3,您可以在必要時處理顯示首選項。如果您要為業務層引入另一個介面,您可能需要通過選擇 2 進行不必要的程式碼迭代。