Могу ли я использовать Dapper для отображения таблиц SQL с несколькими взаимосвязями? - PullRequest
0 голосов
/ 09 апреля 2019

Я разрабатываю настольное приложение C # WPF, в котором мне нужно регулярно читать / писать в базу данных SQL (сервер SQL). Теперь я хочу отобразить данные из базы данных на объекты в C #. Я не могу использовать Entity Framework, поэтому я делаю все доступ к данным через Dapper и хранимые процедуры.

В качестве примера я смоделировал этот пример базы данных

enter image description here

Объекты C # будут выглядеть примерно так.

public class Manager {

   public string Name { get; set; }
   public string Phone { get; set; }
   public List<Facility> Facilities {get; set;}
} 

public class City {

   public string Name { get; set; }
   public string Description{ get; set; }
   public List<Facility> Facilities {get; set;}
} 

public class Facility {

   public string Name { get; set; }
   public string Description{ get; set; }
} 

Я пытался отобразить данные с помощью Spperpper Autopper, но это не сработало . Могу ли я использовать Dapper, чтобы отобразить все это? Мне даже нужно сопоставить каждую таблицу с классом в C # с его отношениями? Или я мог бы просто написать хранимую процедуру, которая возвращает все совпадающие записи, и создать один большой класс со всеми данными в качестве свойств?

1 Ответ

1 голос
/ 09 апреля 2019

Вы можете использовать Dapper, чтобы заставить его работать, и у вас есть несколько вариантов:

Первый вариант

Вы можете запросить родительский объект, а затем запросить все дочерние объекты,Код будет выглядеть следующим образом:

var manager = await connection.QueryFirstOrDefaultAsync<Manager>("SELECT * FROM Manager AS m WHERE m.Name = @name", new {name = name}); // use your query and your parameters

manager.Facilities = await connection.QueryAsync<Manager>("SELECT * FROM Facilities AS f WHERE f.ManagerId = @managerId", new {managerId = manager.ManagerId}); 

// use similar queries to get Cities

Второй параметр

Вы можете использовать multimapping , чтобы получить несколько объектов (но вы должны знать,что он позволяет запрашивать до 7 зависимых объектов - для вашего случая этого будет достаточно):

public async Task<IEnumerable<Manager>> GetManagerWithFacilitiesByManagerName(string name)
{
    var managersDictionary = new Dictionary<int, Manager>();

    await connection.Query<Manager, Facility, Manager>(
       @"SELECT * 
         FROM Manager AS m 
         INNER JOIN Facilities as f ON f.ManagerId = m.ManagerId
         WHERE m.Name = @name", 
       (manager, facility) => 
       { 
           Manager managerEntity;

           if (managersDictionary.ContainsKey(manager.ManagerId)
           {
               managerEntity = managersDictionary[manager.ManagerId];
           } 
           else 
           {
               managerEntity = manager;
               managerEntity.Facilities = new List<Facilities>();
               managersDictionary.Add(managerEntity.ManagerId, managerEntity);
           }

           managerEntity.Facilities.Add(facility);

           return managerEntity;
       }
       new {name = name},
       splitOn: "ManagerId,FacilityId") // properties where to split entity

    return managersDictionary.Values;    
} 

Если вы хотите только сначала Manager, просто используйте managersDictionary.Values.FirstOrDefault() и измените тип возврата на Task<Manager>.

...