#c# #sql-server #dapper
Вопрос:
Это мои занятия:
public class InvoiceModel
{
public int Id { get; set; }
public CustomerModel Customer { get; set; }
public string DateCreated { get; set; }
public ObservableCollection<InvoiceItemModel> Items { get; set; }
public ObservableCollection<InvoicePaymentModel> Payments { get; set; }
}
public class CustomerModel
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public ObservableCollection<PhoneNumberModel> PhoneNumbers { get; set; }
}
public class PhoneNumberModel
{
public int CustomerId { get; set; }
public string PhoneNumber { get; set; }
}
public class InvoiceItemModel
{
public int Id { get; set; }
public int InvoiceId { get; set; }
public int ProductId { get; set; }
public long SellPrice { get; set; }
public int Count { get; set; }
}
public class InvoicePaymentModel
{
public int InvoiceId { get; set; }
public string DateCreated { get; set; }
public double PayAmount { get; set; }
}
У меня также есть эти таблицы в SQL Server: Клиенты, номера телефонов, Счета-фактуры, элементы счетов-фактур и платежи по счетам, которые вы можете угадать по столбцам.
Как я могу сопоставить эти классы с помощью Dapper?
Я знаю, что могу использовать SplitOn
карту клиента в счетах-фактурах, но я ищу решение, позволяющее сделать все это за один раз (с наименьшими затратами на сервер и клиента). Я знаю, что должен использовать QueryMultiple
, но я не знаю как.
Я использую C# и SQL Server 2017
Я использую ObservableCollection
, потому что я использую Caliburn Micro. РЕДАКТИРОВАТЬ Я извлекаю набор InvoiceModel
из БД ( ObservableCollection<InvoiceModel>
)
Комментарии:
1. Почему за 1 заход? это закончится большим количеством группировок на стороне клиента, вместо того, чтобы получать небольшие пакеты данных из БД … я бы пошел с получением InvoiceModel с
Id
иDateCreated
, затем для каждогоId
я бы: получилCustomerModel
с присоединением кPhoneNumberModel
, затемItems
, затемPayments
…2. или… для списка я бы использовал другую модель fx
InvoiceModelForList
с суммой и количествомItems
иPayments
и fx в первуюPhoneNumberModel
очередь, так как пользователю не нужна вся информация в списке …3. Под «Одним заходом» я подразумевал наименьшие накладные расходы на сервер и клиент. и когда я редактировал свой вопрос, я пытался заполнить набор моделей счетов, чтобы
ObservableCollection<InvoiceModel>
4. На самом деле мне нужна полная информация. потому что, когда пользователь пытается просмотреть счет-фактуру через список, выбранная модель счета-фактуры отправляется в ViewModel средства просмотра, в котором я хочу показать почти всю информацию о счете-фактуре. Я также могу выполнить запрос, как вы советовали, а затем выполнить другой запрос, когда пользователь захочет просмотреть счет, но я думаю, что меньше запросов, лучшая производительность, не так ли ? Кстати, я не знаю подходящего кода на C# для всего этого.
Ответ №1:
Используйте этот синтаксис
var model = new InvoiceModel
{
Customer = new CustomerModel
{
PhoneNumbers = new ObservableCollection<PhoneNumberModel>()
}
};
var sql = "Your Select Query";
using (var connection = new SqlConnection("Your Connection String"))
{
connection.Open();
var parameters = new DynamicParameters();
//If you have parameteres add like here
//parameters.Add("@Id", 1, DbType.Int32);
using (var multi = connection.QueryMultiple(sql, parameters))
{
model = multi.Read<InvoiceModel>().FirstOrDefault();
model.Customer = multi.Read<CustomerModel>().FirstOrDefault();
var items = multi.Read<InvoiceItemModel>().ToList();
var payments = multi.Read<InvoicePaymentModel>().ToList();
model.Items = new ObservableCollection<InvoiceItemModel>(items);
model.Payments = new ObservableCollection<InvoicePaymentModel>(payments);
}
}
Редактировать :
Для загрузки ObservableCollection<InvoiceModel>
Используйте Этот Синтаксис
using (var connection = new SqlConnection("Your Connection string"))
{
connection.Open();
var sqlCommand = "select * from InvoiceModels as ic inner JOIN"
" CustomerModel AS cm on ic.CustomerId = cm.Id ";
var invoices = connection.Query(sqlCommand, new[] { typeof(InvoiceModel), typeof(CustomerModel), }, obj =>
{
var invoiceModel = obj[0] as InvoiceModel;
invoiceModel.Customer = obj[1] as CustomerModel;
return invoiceModel;
}).ToList();
var obserInvoices = new ObservableCollection<InvoiceModel>(invoices);
for (int i = 0; i < obserInvoices.Count; i )
{
var phoneNumbers = connection.Query<PhoneNumberModel>
("Select * from PhoneNumberModel Where CustomerModelId=@Id", new { @Id = obserInvoices[i].CustomerId }).ToList();
if (phoneNumbers.Any())
obserInvoices[i].Customer.PhoneNumbers = new ObservableCollection<PhoneNumberModel>(phoneNumbers);
var invoiceItemModel = connection.Query<InvoiceItemModel>
("Select * from InvoiceItemModel Where InvoiceModelId=@Id", new { @Id = obserInvoices[i].Id }).ToList();
if (invoiceItemModel.Any())
obserInvoices[i].Items = new ObservableCollection<InvoiceItemModel>(invoiceItemModel);
var invoicePaymentModel = connection.Query<InvoicePaymentModel>
("Select * from InvoicePaymentModel Where InvoiceModelId=@Id", new { @Id = obserInvoices[i].Id }).ToList();
if (invoicePaymentModel.Any())
obserInvoices[i].Payments = new ObservableCollection<InvoicePaymentModel>(invoicePaymentModel);
}
}
Комментарии:
1. мамнун дадаш, Ваш код, похоже, подходит для извлечения одного
Invoice
из базы данных и будет полезен мне для другой части проекта, но сейчас я запрашиваю базу данных для нескольких счетов-фактур (ObservableCollection<InvoiceModel>
). Я использую ручную нумерацию страниц, с помощьюSelect Top(x)
которой выбирается набор счетов-фактур.2. Горбонет , Для Загрузки (
ObservableCollection<InvoiceModel>
) Используйте приведенный выше код