我可以使用Dapper映射具有多个关系的SQL表吗?

问题描述 投票:-1回答:1

我正在开发一个C#WPF桌面应用程序,我需要定期读/写SQL数据库(SQL服务器)。现在我想将数据库中的数据映射到C#中的对象。我不能使用实体框架,所以我通过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; }
} 

我试图用slapper automapper映射数据,但it didn't工作。我可以使用Dapper来映射所有这些吗?我是否甚至需要将每个Table映射到C#中的一个类及其关系?或者我可以编写一个存储过程来返回已匹配的所有条目,并创建一个包含所有数据作为属性的大类?

c# sql sql-server database dapper
1个回答
1
投票

你可以使用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>

© www.soinside.com 2019 - 2024. All rights reserved.