C# 使用Dapper或via Linq填充一对多关系
实体-C# 使用Dapper或via Linq填充一对多关系,c#,linq,one-to-many,dapper,C#,Linq,One To Many,Dapper,实体-AllSalesTerritory包含表示一对多关系的List。我使用Sql查询来获取使用列TerritoryId映射两个实体的数据。我使用以下代码使用Dapper micro ORM填充实体: List<AllSalesTerritory> allSalesTerrotories = _connection.Query<AllSalesTerritory, MySalesPerson, AllSalesTerritory> (qu
AllSalesTerritory
包含表示一对多关系的List
。我使用Sql
查询来获取使用列TerritoryId
映射两个实体的数据。我使用以下代码使用Dapper micro ORM
填充实体:
List<AllSalesTerritory> allSalesTerrotories = _connection.Query<AllSalesTerritory, MySalesPerson, AllSalesTerritory>
(query, (pd, pp) =>
{
pd.SalesPersons.Add(pp);
return pd;
}, splitOn: "BusinessEntityId")
.ToList();
列出所有SalesTerrotories=\u connection.Query
(查询,(pd,pp)=>
{
pd.销售人员。添加(pp);
返回pd;
},splitOn:“BusinessEntityId”)
.ToList();
BusinessEntityId
是执行Sql语句时SalesPerson实体的起始列
我面临的挑战是,这种代码有助于轻松填充一对一关系,在这里,我在每个列表中只得到一个值,而不是在集合中聚合这些值,基本上与SQL join查询的结果相同。我可以使用一个简单的foreach
循环并聚合MySalesPerson
的值来轻松解决这个问题。然而,我想弄清楚:
Dapper可以自动帮助我实现它吗?尝试了一些扩展,但它们并没有按预期工作
Linq代码可以为我做到这一点吗?因为这与具有一对多关系的实体上的SelectMany
有些相反
您可以使用字典跟踪唯一的AllSalesTerritory
对象。假设TerritoryId
属性是int
,这将起作用
var territories = new Dictionary<int, AllSalesTerritory>()
_connection.Query<AllSalesTerritory, MySalesPerson, AllSalesTerritory>
(query, (pd, pp) =>
{
AllSalesTerritory territory;
if(!territories.TryGetValue(pd.TerritoryId, out territory))
{
territories.Add(pd.TerritoryId, territory = pd);
}
territory.SalesPersons.Add(pp);
return territory;
}, splitOn: "BusinessEntityId");
List<AllSalesTerritory> allSalesTerrotories = territories.Values.ToList();
var=newdictionary()
_连接.查询
(查询,(pd,pp)=>
{
所有销售区域;
如果(!Territions.TryGetValue(pd.TerritoryId,out territory))
{
地区。添加(pd.TerritoryId,territory=pd);
}
地区。销售人员。添加(pp);
返回领土;
},splitOn:“BusinessEntityId”);
列出所有SalesTerrotories=Territies.Values.ToList();
这里发生的基本情况是Dapper将为查询结果中的每一行返回一个AllSalesTerritory
和一个MySalesPerson
。然后,我们使用字典查看当前的AllSalesTerritory
(pd
)是否基于TerritoryId
。如果是,则本地区域
变量被指定该对象的引用。如果没有,那么我们将pd
分配给territory
,然后将其添加到字典中。然后,我们只需将当前的MySalesPerson
(pp
)添加到territory.Salesors
列表中。谢谢,它确实有效,让我看看是否可以得到Dapper直接处理问题的响应,但是有一个问题,尽管我没有使用Dictionary,但您的解决方案也将AllSalesTerritory声明为局部变量,那么它如何在映射函数中对销售人员进行内部聚合。除了第一次,我们甚至还在从字典里取。我肯定漏掉了什么,这就是这本词典的用意。它跟踪唯一的AllSalesTerritory
项目。我会在答案中添加一些描述。明白了。非常感谢,我完全遗漏了TryGetValue中的“外部区域”,它负责参考任务,因此,在分配到字典的过程中,它第一次是本地的,在字典上它是使用字典获取的,事实上,这就是为什么我们可能没有使用_connection.Query的结果,这将导致与我的问题类似的结果。如果我通过Dapper获得解决方案,那么这将作为_connection.Query的结果提供。在把你的答案标记为正确答案之前,我会等待一段时间,等待一个纯粹简洁的答案。谢谢你的帮助。据我所知,没有比简洁更自然的方法了。另外,查询的结果
将包含正确的对象,但会有重复的引用。可能重复了您所引用的链接中提到的Slapper.Automapper,但它没有按预期工作,导致在dapper扩展二进制中中止调用,毫无例外,我个人从未使用过Slapper.AutoMapper,但这个问题肯定是重复的。它甚至有像我一样的字典答案。此外,这也是Dapper的创建者之一提出的相关内容。感谢@juharr,Sam的解决方案为我提供了开箱即用的解决方案,只需在GroupBy完成时对空键进行一点修改,否则字典就无法处理空键