Я занимаюсь преобразованием большого классического ASP-приложения в ASP.Net MVC с использованием подхода n-уровня. В моем DAL я использую ADO.Net для запроса базы данных и преобразования запросов в объекты. У меня также есть BLL для таких вещей, как вычисления и валидация.Расчеты в слое доступа к данным
Мой вопрос касается выполнения вычислений в DAL, когда необходимы вычисления для преобразования запроса в объекты. Чтобы дать пример рассмотрит систему выставления счетов-фактур с итоговой информацией, а также позиции:
public class Invoice
{
public int InvoiceID { get; set; }
public DateTime InvoiceDate { get; set; }
public decimal InvoiceTotal { get; set; }
public List<InvoiceLineItem> LineItemList { get; set; }
}
Так что мой код для преобразования позиции в запросе к базе данных будет выглядеть следующим образом:
decimal InvoiceTotal = 0;
var LineItem = new InvoiceLineItem();
while (Reader.Read())
{
LineItem.ItemID = Extensions.SafeGetInt(Reader, "ItemID");
LineItem.Price = Extensions.SafeGetDecimal(Reader, "Price");
LineItem.Quantity = Extensions.SafeGetInt(Reader, "Quantity");
LineItemList.Add(LineItem);
InvoiceTotal = InvoiceTotal + (LineItem.Price * LineItem.Quantity);
}
Invoice.InvoiceTotal = InvoiceTotal;
etc ...
Так вот мой вопрос: учитывая мою n-ярусную архитектуру, является ли мое DAL правильным местом для выполнения расчета InvoiceTotal? Учитывая, что часть работы BBL заключается в выполнении расчетов, нарушает ли это разделение проблем между DAL и BLL? Или я беру функцию BBL для выполнения вычислений слишком буквально, и нормально делать вычисления в DAL, если эти вычисления необходимы для заполнения модели? Одна из причин, почему я считаю целесообразным делать расчет InvoiceTotal в DAL, заключается в том, что мне нужно только один раз перебирать записи элементов счета. Если бы я создал отдельную функцию InvoiceTotal в другом месте, чтобы получить InvoiceTotal, тогда мне пришлось бы повторять итерацию по записям во второй раз.
Редактировать: Оказывается, что реальный вопрос заключается не в том, должны ли вычисления быть допустимыми в DAL, а в том, должен ли InvoiceTotal быть в моей модели вообще. С точки зрения нормализации базы данных это не требуется, потому что итоговые суммы могут быть рассчитаны из позиций. В этом случае InvoiceTotal не должен находиться в моей модели, но должен быть в моей модели ViewModel, и в этом случае нет необходимости делать вычисления в моем DAL. Я мог игнорировать проблемы с нормализацией базы данных по причинам производительности и включать InvoiceTotal в мою модель, но если это так, я бы сохранил InvoiceTotal в базе данных, и в этом случае при заполнении моей модели никакие вычисления не потребовались бы, так как я просто вытащил бы значение из базы данных.
Извлеченный урок: если у меня возникает соблазн выполнять вычисления в моем DAL, моя модель, скорее всего, будет испорчена.
Средний процессор, возможно, выполняет миллионы итераций в секунду. Это не должно диктовать вашу архитектуру; вычисления относятся к бизнес-уровню. – CodeCaster
Расчеты относятся к бизнес-уровню. Данные Persisting and Querying относятся к слою данных. – MUG4N
CodeCaster, я также пытаюсь быть СУХОЙ. Если я создам отдельную функцию для вычисления суммы счета и повторного повторения записей, я не нарушаю DRY? –