Результаты нескольких сопоставлений SQL Server с использованием Dapper на C#

#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> ) Используйте приведенный выше код