使用Dapper或Linq填充一对多关系
本文关键字:一对多 关系 填充 Linq Dapper 使用 | 更新日期: 2023-09-27 18:15:08
Entity - AllSalesTerritory
包含代表一对多关系的List<MySalesPerson>
。我有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();
BusinessEntityId
是执行Sql语句
我面临的挑战是,这种代码有助于轻松地填充一对一的关系,这里我在每个List<MySalesPerson>
中只获得一个值,而不是将这些值聚集在集合中,本质上与SQL连接查询的结果相同。我可以使用简单的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();
基本上这里发生的事情是,Dapper将返回一个AllSalesTerritory
和一个MySalesPerson
在你的查询结果的每一行。然后,我们使用字典来查看当前AllSalesTerritory
(pd
)是否已经基于TerritoryId
见过。如果是这样,则将本地territory
变量的引用赋给该对象。如果没有,则将pd
赋值给territory
,然后将其添加到字典中。然后我们只需将当前的MySalesPerson
(pp
)添加到territory.SalesPersons
列表中。