2016-07-19 5 views
0

У меня есть служба, которая принимает в качестве параметра ProcessOrdersArgs, который может содержать тысячи объектов Order. Мне нужно проверить на сервере базы данных, что каждый принятый заказ является действительным действительным порядком, который существует. Прямо сейчас, для одного вызова службы, который обрабатывает тысячи заказов, я делаю тысячи обращений в базу данных только для проверки пройденного в заказах, и я хотел бы значительно сократить количество обращений к базе данных для проверки.Как эффективно проверить сбор идентификаторов в базе данных или любом внешнем источнике данных?

У меня есть следующие классы для моей проверки. .CustomerId и .OrderId в моем OrderValidator являются расширениями класса FluentValidation PropertyValidator.

У клиентаIdValidator встроено кэширование, поскольку часто обрабатываются тысячи обрабатываемых заказов, многие из них предназначены для одного и того же клиента, и я хочу разрезать круглые поездки в базу данных при проверке того же 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

ли вы рассмотреть вопрос о включении данных в базу данных? Вы можете создать таблицу с одним столбцом и внешним ключом, ссылающимся на фактические идентификаторы, хранящиеся в базе данных. Если вставка не удалась, в вашем наборе данных есть недопустимый идентификатор. – PacoDePaco

+1

Я знаю много способов проверить список идентификаторов, навалом, против базы данных. Это не вопрос моего вопроса. Я хочу понять, как это сделать с помощью Fluent Validation. Моя проблема заключается в том, что мой валидатор свойств OrderId имеет соединение с БД и должен проверять каждый заказ по отдельности. Я чувствую, что мне нужно подталкивать эту проверку до самого ProcessOrdersArgsValidator и делать там валидацию, возможно, используя метод, аналогичный тому, что вы предлагаете, или что-то еще. Против, я просто не уверен, как это должно выглядеть с Fluent Validation. – Dude0001

ответ

1

Вы можете использовать predicate validatorMust или MustAsync для Orders собственности

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) 
    .... 
}