简体   繁体   English

使用 Dapper SplitOn 时如何映射对象?

[英]How to map objects when using Dapper SplitOn?

I have a stored proc that returns multiple rows which the following columns:我有一个存储过程,它返回多行,其中以下列:

Guid,
Guid,
Name,
Guid,
Description

The first Guid column is always the same for all the rows.所有行的第一个Guid列始终相同。 So I created the following classes:所以我创建了以下类:

public class Header
{
    public Guid Guid { get; set; }
    public string Name { get; set; }
}

public class Content
{
    public Guid Guid { get; set; }
    public string Description { get; set; }
}

public class Result 
{
    public Guid Guid { get; set; }
    public IEnumerable<Header> Headers { get; set; }
    public IEnumerable<Content> Content { get; set; }
}

And to get the reults I'm trying to do:为了得到我想要做的结果:

var result connection.Query<Guid, Header, Content>("myproc", 
    new { criteria }, 
    commandType: CommandType.StoredProcedure,
    map: ,
    splitOn: "Guid").AsList();

But what should I do in the map parameter to split the results into the objects?但是我应该在map参数中做什么来将结果拆分为对象?

I don't think you can call 3 of the 5 columns returned with the same name ( Guid ) and expect Dapper to figure out how to split correctly.我不认为您可以调用以相同名称 ( Guid ) 返回的 5 列中的 3 列,并期望 Dapper 弄清楚如何正确拆分。

Assuming that the column names returned from the SPROC are unique (I've named Guid1 , Guid2 and Guid3 ), we split on Guid2 (header) and Guid2 (content).假设从 SPROC 返回的列名是唯一的(我命名为Guid1Guid2Guid3 ),我们拆分Guid2 (标题)和Guid2 (内容)。

Since the Query will return one row per row returned from the Proc, we need to consolidate and group by the Parent Guid.由于 Query 将从 Proc 返回的每行返回一行,因此我们需要通过 Parent Guid 进行合并和分组。

I've used the Dictionary pattern here to do this rollup:我在这里使用字典模式来做这个汇总:

var sql = "EXEC p_myProc";
var resultDictionary = new Dictionary<Guid, Result>();
var results = connection.Query<Result, Header, Content, Result>(
        sql,
        (result, header, content) =>
        {
            if (!resultDictionary.TryGetValue(result.Guid1, out var existingResult))
            {
                result.Headers = new List<Header>();
                result.Content = new List<Content>();
                resultDictionary.Add(result.Guid1, result);
                existingResult = result;
            }
            // Noting OP has defined the Child tables as immutable IEnumerable<>
            (existingResult.Headers as List<Header>).Add(header);
            (existingResult.Content as List<Content>).Add(content);
            return existingResult;
        },
        splitOn: "Guid2,Guid3")
    .Distinct() // Strip duplicates by reference equality
    .ToList();

Note that the results returned by Query will have as many rows as the proc returns, but because we'll return the same reference Result for each Guid1 key, Distinct() will strip out the duplicates.请注意, Query返回的结果将与 proc 返回的行数一样多,但因为我们将为每个Guid1键返回相同的引用ResultDistinct()Guid1重复项。

An alternative to this approach would be to map the flattened result of the Stored Proc into a 1:1 temporary DTO POCO with all 5 columns, and then use LINQ in memory to GroupBy the Guid1 in order to project out the Header and Content children.这种方法的替代方法是将 Stored Proc 的展平结果映射到具有所有 5 列的 1:1 临时 DTO POCO,然后在内存中使用 LINQ 到Guid1 GroupBy 以投影出HeaderContent子项。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM