使用 Dapper 或通过 Linq 填充一对多关系
Filling one to many relationship using using Dapper or via Linq
实体 - 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 语句时 SalesPerson 实体的起始列
我面临的挑战是,这种代码有助于轻松填充一对一关系,这里我在每个 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 将为查询结果中的每一行 return 一个 AllSalesTerritory
和一个 MySalesPerson
。然后我们使用字典根据TerritoryId
查看当前的AllSalesTerritory
(pd
)是否已经出现过。如果是这样,则局部 territory
变量被分配到该对象的引用。如果不是,那么我们将 pd
分配给 territory
,然后将其添加到字典中。然后我们只是将当前的 MySalesPerson
(pp
) 添加到 territory.SalesPersons
列表中。
实体 - 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 语句时 SalesPerson 实体的起始列
我面临的挑战是,这种代码有助于轻松填充一对一关系,这里我在每个 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 将为查询结果中的每一行 return 一个 AllSalesTerritory
和一个 MySalesPerson
。然后我们使用字典根据TerritoryId
查看当前的AllSalesTerritory
(pd
)是否已经出现过。如果是这样,则局部 territory
变量被分配到该对象的引用。如果不是,那么我们将 pd
分配给 territory
,然后将其添加到字典中。然后我们只是将当前的 MySalesPerson
(pp
) 添加到 territory.SalesPersons
列表中。