Asp.net-Mvc

在控制器中進行 linq 查詢是一種好習慣嗎?

  • December 16, 2018

我對 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 進行不必要的程式碼迭代。

引用自:https://stackoverflow.com/questions/7142492