Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用Dapper高效地选择聚合对象?_C#_Sql_Dapper - Fatal编程技术网

C# 如何使用Dapper高效地选择聚合对象?

C# 如何使用Dapper高效地选择聚合对象?,c#,sql,dapper,C#,Sql,Dapper,假设我有一系列的对象,它们构成了一个集合 public class C{ public string Details {get;set;} } public class B{ public string Details {get;set;} public List<C> Items {get;set;} } public class A{ public long ID {get;set;} public string Details {get;set;} p

假设我有一系列的对象,它们构成了一个集合

public class C{
 public string Details {get;set;}
}

public class B{
  public string Details {get;set;}
  public List<C> Items {get;set;}
}

public class A{
  public long ID {get;set;}
  public string Details {get;set;}
  public List<B> Items {get;set;}
}
公共C类{
公共字符串详细信息{get;set;}
}
公共B级{
公共字符串详细信息{get;set;}
公共列表项{get;set;}
}
公共A类{
公共长ID{get;set;}
公共字符串详细信息{get;set;}
公共列表项{get;set;}
}
使用Dapper,从数据库中的表填充这些数据的最佳方法是什么(在我的例子中是postgres,但这不重要)。示例中的表与对象模型几乎是一对一的。类上的Items属性表示与每个从属对象的外键关系。i、 e.3表,A与B有一对多关系,B与C有一对多关系

因此,对于给定的ID,我希望我的对象也具有其所有子数据


我最好的猜测是,我应该以某种方式使用QueryMultiple,但我不确定如何最好地使用它。

我想我在这里建议的助手:可能会有所帮助

var mapped = cnn.QueryMultiple(sql)
   .Map<A,B,A>
    (
       A => A.ID, 
       B => B.AID,
       a, bees => { A.Items = bees};  
    );
var-mapped=cnn.QueryMultiple(sql)
.地图
(
A=>A.ID,
B=>B.AID,
a、 蜜蜂=>{a.Items=bees};
);
假设您使用映射器扩展GridReader:

public static IEnumerable<TFirst> Map<TFirst, TSecond, TKey>
    (
    this GridReader reader,
    Func<TFirst, TKey> firstKey, 
    Func<TSecond, TKey> secondKey, 
    Action<TFirst, IEnumerable<TSecond>> addChildren
    )
{
    var first = reader.Read<TFirst>().ToList();
    var childMap = reader
        .Read<TSecond>()
        .GroupBy(s => secondKey(s))
        .ToDictionary(g => g.Key, g => g.AsEnumerable());

    foreach (var item in first)
    {
        IEnumerable<TSecond> children;
        if(childMap.TryGetValue(firstKey(item), out children))
        {
            addChildren(item,children);
        }
    }

    return first;
}
公共静态IEnumerable映射
(
这个网格阅读器,
Func firstKey,
Func secondKey,
儿童行动
)
{
var first=reader.Read().ToList();
var childMap=读取器
.读()
.GroupBy(s=>secondKey)
.ToDictionary(g=>g.Key,g=>g.AsEnumerable());
foreach(第一个变量项)
{
数不清的孩子;
if(childMap.TryGetValue(第一个键(项),输出子项))
{
添加子项(项目,子项);
}
}
先返回;
}

您可以扩展此模式以使用3级层次结构

可能是
QueryMultiple
方法?我刚下载了dapper。。假设您指的是“dapper dot net”。是的,dapper dot net是我正在试验的。我目前正在对所有不同的表进行查询,然后使用linq按id分配给子集合。这意味着我对数据库进行了一批处理,并在ram中完成了所有工作,而不是像我所看到的linq2sql那样,对数据库进行了大量的偶然查询……我对结果非常满意,我只是想知道我的方法是否是整洁的作者的意图。目前我们没有运行身份管理器,所以你会得到dups。我必须要有一个剧本来解决这个问题。谢谢@Marc,我期待着看到你的想法。我很满意我目前的手动处理方式,但是身份管理是一个额外的好处。这对我不起作用。当它试图读取TSecond时,读卡器已被使用,无法再次读取。谢谢Sam,我通过修改查询使其正常工作。使用了类似于您在本文中建议的内容