使用Dapper或通过Linq填充一对多关系

Mri*_*boj 5 c# linq one-to-many dapper

实体 - 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();
Run Code Online (Sandbox Code Playgroud)

BusinessEntityId 是SalesPerson实体在执行Sql语句时的开始列

我面临的挑战是,这种代码有助于轻松填充一对一关系,这里我只获得一个值List<MySalesPerson>,而不是在集合中聚合这些值,基本上与SQL连接查询的结果相同.我可以使用简单的foreach循环并聚合值来轻松解决问题MySalesPerson.但是,我想弄明白:

  1. Dapper可以自动帮助我实现它,尝试了一些扩展,但它们没有按预期工作
  2. Linq代码可以为我做,因为这SelectMany与具有一对多关系的实体有些相反

juh*_*arr 13

您可以使用字典来跟踪唯一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();
Run Code Online (Sandbox Code Playgroud)

基本上这里发生的是Dapper将在查询结果中为每一行返回一个AllSalesTerritory和一个MySalesPerson.然后我们使用字典来查看之前是否已经看过current AllSalesTerritory(pd)TerritoryId.如果territory是,则为局部变量分配对该对象的引用.如果没有,那么我们分配pdterritory,然后添加到字典中.然后我们只需将current MySalesPerson(pp)添加到territory.SalesPersons列表中.