将 Dapper 查询映射到对象集合(它本身有几个集合)
Posted
技术标签:
【中文标题】将 Dapper 查询映射到对象集合(它本身有几个集合)【英文标题】:Mapping Dapper Query to a Collection of Objects (which itself has a couple of Collections) 【发布时间】:2012-05-09 11:16:37 【问题描述】:我想执行单个查询(或具有多个结果集的存储过程)。我知道如何使用 Dapper 进行多重映射,但我无法排序如何将两个集合映射到同一个父级。基本上,给定这个对象定义......
class ParentObject
string Name get; set;
ICollection<ChildObjectOne> ChildSetOne get;set;
ICollection<ChildObjectTwo> ChildSetTwo get; set;
class ChildObjectOne
string Name get; set;
class ChildObjectTwo
int id get; set;
string LocationName get; set;
我希望能够运行以某种方式产生的 Dapper 查询:
IQueryable<ParentObject> result = cnn.Query(
// Some really awesome dapper syntax goes here
);
【问题讨论】:
【参考方案1】:不确定您是否不想使用 MultiMapping,但以下是它适用于您的情况的方法。据我所知并阅读 SO,不可能用简单的Query
映射深层嵌套对象图。
static void Main(string[] args)
var sqlParent = "SELECT parentId as Id FROM ParentTable WHERE parentId=1;";
var sqlChildOneSet = "SELECT Name FROM ChildOneTable;"; // Add an appropriate WHERE
var sqlChildTwoSet = "SELECT Id, LocationName FROM ChildTwoTable;"; // Add an appropriate WHERE
var conn = GetConnection() // whatever you're getting connections with
using (conn)
conn.Open();
using (var multi = conn.QueryMultiple(sqlParent + sqlChildOneSet + sqlChildTwoSet))
var parent = multi.Read<ParentObject>().First();
parent.ChildSetOne = multi.Read<ChildOne>().ToList();
parent.ChildSetTwo = multi.Read<ChildTwo>().ToList();
嵌套对象和 dapper 的类似问题:
https://***.com/search?q=nested+objects+%2B+dapper
【讨论】:
【参考方案2】:在这种情况下,可以使用IEnumerable<TReturn> Query<TFirst, TSecond, TThird, TReturn>(this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TReturn> map);
方法实现具有一对多关系的对象。但是,您需要对实体进行一些更改才能获得足够的信息。
这里有一些类似问题的 SO 主题。
How do I map lists of nested objects with Dapper
Extension function to make it cleaner
Dapper.Net by example - Mapping Relationships
public class ParentObject
public ParentObject()
ChildSetOne = new List<ChildObjectOne>();
ChildSetTwo = new List<ChildObjectTwo>();
// 1) Although its possible to do this without this Id property, For sanity it is advisable.
public int Id get; set;
public string Name get; set;
public ICollection<ChildObjectOne> ChildSetOne get; private set;
public ICollection<ChildObjectTwo> ChildSetTwo get; private set;
public class ChildObjectOne
// 2a) Need a ParentId
public int ParentId get; set;
public string Name get; set;
public class ChildObjectTwo
// 2b) This ParentId is not required but again for sanity it is advisable to include it.
public int ParentId get; set;
public int id get; set;
public string LocationName get; set;
public class Repository
public IEnumerable<ParentObject> Get()
string sql =
@"SELECT
p.Id,
p.Name,
o.Name,
o.ParentId,
t.Id,
t.LocationName,
t.ParentId
FROM
Parent p
LEFT JOIN ChildOne o on o.ParentId = p.Id
LEFT JOIN ChildTwo t on t.ParentId = p.Id
WHERE
p.Name LIKE '%Something%'";
var lookup = new Dictionary<int, ParentObject>();
using (var connection = CreateConnection())
connection.Query<ParentObject, ChildObjectOne, ChildObjectTwo, ParentObject>(
sql, (parent, childOne, childTwo) =>
ParentObject activeParent;
if (!lookup.TryGetValue(childOne.ParentId, out activeParent))
activeParent = parent;
lookup.add(activeParent.Id, activeParent);
//TODO: if you need to check for duplicates or null do so here
activeParent.ChildSetOne.Add(childOne);
//TODO: if you need to check for duplicates or null do so here
activeParent.ChildSetTwo.Add(childTwo);
);
return lookup.Values;
【讨论】:
以上是关于将 Dapper 查询映射到对象集合(它本身有几个集合)的主要内容,如果未能解决你的问题,请参考以下文章