2016-07-19 20 views
0

我有一個服務,它的參數ProcessOrdersArgs可以包含數千個Order對象。我需要對數據庫服務器進行驗證,每個訂單傳遞的是實際有效的訂單。現在,對於處理數千個訂單的單個服務調用,爲了驗證傳入的訂單,我正在向數據庫進行數千次往返,我希望顯着減少用於驗證的數據庫往返次數。如何根據數據庫或任何外部數據源高效地驗證Ids集合?

我有我的驗證以下相關的類。 。我的OrderValidator中的.CustomerId和.OrderId是FluentValidation PropertyValidator類的擴展。

CustomerIdValidator內置了緩存,因爲經常處理數千個訂單,許多是針對同一個客戶的,我想在驗證相同的CustomerId時削減往返數據庫的往返行程。

我想做一些與OrderIds類似的事情,並限制數據庫往返的次數,但緩存不是解決方案,因爲每個OrderId可能有數千個將是唯一的。我想批量驗證這些OrderIds。我的想法是批量複製每個客戶端的OrderIds列表,並返回無效OrderIds列表(如果有的話)作爲驗證錯誤報告。

我該如何做,或者是否有另一種方式需要構建我的驗證,以便我可以批量驗證訂單而不是進行數千次往返數據庫調用?

public class Order 
{ 
    public int CustomerId { get; set; } 
    public int OrderId { get; set; } 
} 

public class ProcessOrdersArgs 
{ 
    public List<Order> Orders { get; set; } 
} 

public class ProcessOrdersArgsValidator : AbstractValidator<ProcessOrdersArgs> 
{ 
    public ProcessOrdersArgsValidator(OrderValidator orderValidator) 
    { 
     RuleFor(a => a.Orders) 
      .SetCollectionValidator(orderValidator); 
    } 
} 

public class OrderValidator : AbstractValidator<Order> 
{ 
    public OrderValidator(DBConnection dbConnection) 
    { 
     RuleFor(c => c.CustomerId) 
      .CustomerId(dbConnection); 

     RuleFor(c => c.OrderId) 
      .OrderId(dbConnection, c => c.CustomerId); 
    } 
} 
+0

你考慮將數據插入到數據庫?您可以創建一個包含一列和一個外鍵的表,並引用存儲在數據庫中的實際ID。如果插入失敗,則數據集中存在無效的ID。 – PacoDePaco

+1

我知道許多方法來批量驗證數據庫中的ID列表。這不是我的問題的重點。我想了解如何使用Fluent驗證來做到這一點。我的問題是我的OrderId屬性驗證器有一個數據庫連接,並且必須單獨驗證每個OrderId。我覺得我需要將此驗證推送到ProcessOrdersArgsValidator本身,並在其中批量驗證,也許使用類似於您所建議的方法或其他方法。反對,我只是不確定如何使用Fluent驗證看起來應該如何。 – Dude0001

回答

1

您可以使用predicate validatorMustMustAsyncOrders財產

public class ProcessOrdersArgsValidator : AbstractValidator<ProcessOrdersArgs> 
{ 
    public ProcessOrdersArgsValidator(DBConnection dbConnection) 
    { 
     RuleFor(a => a.Orders).Must(orders => 
     { 
      var ids = orders.Select(o => o.OrderId); 

      return BulkValidateIds(ids, dbConnection); 
     }); 
    } 

    private bool BulkValidateIds(IEnumerable<int> ids, DBConnection dbConnection) 
    .... 
}