我有一个查询来获取单个文档:-
SELECT doc.Id
,doc.Type
,doc.Name
,doc.Description
,doc.File
,doc.CreatedAt
,doc.UpdatedAt
,dl.LabelId
,l.Name
,l.Description
,dc.DocumentId
,dc.ProfileId
,dc.Role
FROM Documents as doc
LEFT JOIN DocumentCollaborators as dc
ON doc.Id = dc.DocumentId
LEFT JOIN DocumentLabels as dl
ON doc.Id = dl.DocumentId
LEFT JOIN Labels as l
ON dl.LabelId = l.Id
WHERE doc.Id = @Id
我用 Dapper 查询这个问题如下:
var documents = await connection.QueryAsync<DocumentDto, LabelDto, CollaboratorDto, DocumentDto>(
GetDocumentSql,
(doc, label, collaborator) => {
if (label.LabelId != Guid.Empty) // empty guid means no label
{
doc.Labels.Add(label);
}
if (collaborator.ProfileId != Guid.Empty) // empty guid means no collaborator
{
doc.Collaborators.Add(collaborator);
}
return doc;
},
new
{
Id = documentId.ToString()
},
splitOn: "LabelId,DocumentId");
我的DTO如下:
public abstract class BaseDocumentDto
{
public Guid Id { get; set; }
public int Type { get; set; }
public string Name { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public string File { get; set; } = string.Empty;
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
}
public class DocumentDto : BaseDocumentDto
{
public IList<LabelDto> Labels { get; set; } = new List<LabelDto>();
public IList<CollaboratorDto> Collaborators { get; set; } = new List<CollaboratorDto>();
}
public class LabelDto
{
public Guid LabelId { get; set; }
public string Name { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
}
public class CollaboratorDto
{
public Guid ProfileId { get; set; }
public int Role { get; set; }
}
如果我尝试在数据库有多个标签或协作者记录的情况下运行此程序,那么我只能得到返回的第一个记录
DocumentDTO
。
我做错了什么?
这是您做错的地方:您假设结果集中第二行中的文档与第一行中的文档相同。事实并非如此,每行都会有一个新的
doc
。相反,这样做:
DocumentDto myDoc = null;
var documents = await connection.QueryAsync<DocumentDto, LabelDto, CollaboratorDto, DocumentDto>(
GetDocumentSql, (doc, label, collaborator) =>
{
if (myDoc is null)
{
myDoc = doc;
}
if (label.LabelId != Guid.Empty) // empty guid means no label
{
myDoc.Labels.Add(label);
}
if (collaborator.ProfileId != Guid.Empty) // empty guid means no collaborator
{
myDoc.Collaborators.Add(collaborator);
}
return null; // Your data is in myDoc, no need to return anything
},
new
{
Id = documentId.ToString()
},
splitOn: "LabelId,DocumentId");
// Go ahead and use myDoc