Я работаю над приложением в WinForms. Мои данные хранятся на сервере MSSQL (Azure). Часть моего приложения включает в себя некоторые основные функции биллинга. Одна модель, которую я имею, - Счета, но я столкнулся с довольно проблемой производительности. Мой первый вопрос на самом деле: кто виноват? Мой плохо оптимизированный код или базовая структура сущностей. Основная проблема заключается в том, что я отображаю список счетов в DataGridView. Для каждого счета, который я перечисляю, мне нужно сделать несколько вызовов DBContext. Это неразумно? По этой причине мне нужно сделать несколько звонков; один, чтобы получить список счетов для отображения (на основе идентификатора клиента FK), а затем для каждой модели счета-фактуры я вызываю некоторые методы, которые вычисляют такие вещи, как SubTotal, TaxTotal и т. д. Эти функции приведены ниже.
public decimal SubTotal()
{
decimal subtotal = 0;
List<Billing_InvoiceItems> LineItems = db.Billing_InvoiceItems.Where(a => a.InvoiceID == this.id).AsNoTracking().ToList();
{
foreach (var LineItem in LineItems)
subtotal += (LineItem.Cost * LineItem.Quantity);
}
return subtotal;
}
public decimal TaxTotal()
{
decimal taxtotal = 0;
List<Billing_InvoiceItems> LineItems = db.Billing_InvoiceItems.Where(a => a.InvoiceID == this.id).AsNoTracking().ToList();
foreach (var LineItem in LineItems)
{
if (LineItem.Taxable)
{
taxtotal += LineItem.Cost * (decimal) LineItem.TaxPercentage;
}
}
return taxtotal;
}
public decimal Total()
{
return (this.SubTotal() + this.TaxTotal());
}
public decimal TotalDue()
{
return (this.Total() - this.TotalPaid());
}
public decimal TotalPaid()
{
List<Billing_PaymentToInvoice> paymentsToInvoice = db.Billing_PaymentToInvoice.Where(a => a.InvoiceID == this.id).ToList();
decimal totalpaid = 0;
foreach (var Payment in paymentsToInvoice)
{
totalpaid += (decimal)Payment.AmountApplied;
}
return totalpaid;
}
Являюсь ли я необоснованным из-за необходимости делать несколько SQL-запросов на один счет, который я перечисляю? Или я могу оптимизировать эти функции? Я попробовал один подход, чтобы кэшировать элементы счета-фактуры (что позволяет мне вычислять итоги для отображения пользователю). Однако для этого мне потребовалась функция, которую я, казалось бы, часто вызывал, чтобы поддерживать кэш в актуальном состоянии.
РЕДАКТИРОВАТЬ: вы увидите .AsNoTracking () там в запросе LineItems, это была попытка оптимизировать его из некоторого поиска в Интернете.