我正在开发C#WPF桌面应用程序,需要定期读取/写入SQL数据库(SQL Server)。现在,我想将数据库中的数据映射到C#中的对象。我无法使用实体框架,因此我正在通过Dapper和存储过程进行所有数据访问。
作为一个例子,我已经为这个示例数据库建模
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; }
}
我尝试使用拍板自动映射器映射数据,但是it didn't可以工作。我可以使用Dapper映射所有这些吗?我什至需要将每个表及其关系映射到C#中的类吗?还是我可以编写一个存储过程来返回所有已匹配的条目,并创建一个将所有数据作为属性的大类?
答案 0 :(得分: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>
。