我有一个存储过程,返回多行,其中包含以下列:
Guid,
Guid,
Name,
Guid,
Description
所有行的第一个Guid
列始终相同。所以我创建了以下类:
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; }
}
为了得到我想要做的结果:
var result connection.Query<Guid, Header, Content>("myproc",
new { criteria },
commandType: CommandType.StoredProcedure,
map: ,
splitOn: "Guid").AsList();
但是,我应该在map
参数中将结果拆分为对象?
我不认为您可以调用返回的具有相同名称(Guid
)的5列中的3列,并期望Dapper找出如何正确分割。
假设从SPROC返回的列名是唯一的(我将其命名为Guid1
,Guid2
和Guid3
),我们将分为Guid2
(header)和Guid2
(content)。
由于Query将从Proc返回的每行返回一行,因此我们需要通过Parent Guid进行整合和分组。
我用Dictionary pattern here来做这个汇总:
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();
请注意,Query
返回的结果将包含proc返回的行数,但因为我们将为每个Result
键返回相同的引用Guid1
,Distinct()
将删除重复项。
这种方法的另一种方法是将存储过程的扁平化结果映射到具有所有5列的1:1临时DTO POCO,然后在内存中使用LINQ来组合Guid1
以便投射出Header
和Content
子项。