Usar Dapper para asignar objetos anidados que no funcionan

c# dapper

Pregunta

El problema

En pocas palabras, la asignación no funciona como se esperaba. El reason variable local vuelve a ser nulo, por lo que la asignación a nav establece el objeto anidado Reason para anular también.

¿Me estoy perdiendo algo simple aquí?

El procedimiento almacenado

ALTER PROCEDURE [PA].[spGetDocumentNavById]
-- Add the parameters for the stored procedure here
@DocumentNavID INT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;

-- Insert statements for procedure here
SELECT
    dn.DocumentNavID,
    dn.IssuerName,
    nt.Name,
    dn.Amount,
    dn.BTF,
    dn.NavDate,
    dn.ReceivedDate,
    dn.PrimaryIdentifier,
    dn.AssetID,
    dh.LastModifiedBy,
    dh.IsApproved,
    dh.Corrected,
    dh.ReasonID
FROM PA.DocumentNavs dn WITH(NOLOCK)
    JOIN PA.NAVTypes nt WITH(NOLOCK)
        ON nt.NAVTypeID = dn.NavTypeID
    LEFT JOIN PA.DocumentsHistory dh WITH(NOLOCK)
        ON dh.DocumentID = dn.DocumentID
    LEFT JOIN PA.Analysts a WITH(NOLOCK)
        ON a.AnalystID = dh.LastModifiedBy
WHERE dn.DocumentNavID = @DocumentNavID

La C#

public DocumentNav FindById(int documentNavId)
    {
        var data = new
        {
            documentNavId
        };

        using (var conn = SqlConnection)
        {
            var response = conn.Query<DocumentNav, Reason, DocumentNav>("[PA].spGetDocumentNavById",
                map: (nav, reason) =>
                {
                    nav.Reason = reason;
                    return nav;
                }, param: data, splitOn: "ReasonID", commandType: System.Data.CommandType.StoredProcedure)
                .DefaultIfEmpty().FirstOrDefault();

            return response;
        }
    }

Respuesta popular

Dapper puede dividir la consulta de fila devuelta por columnas Id ("Id" o "id"). Si su clave principal es diferente o si desea dividir la fila en un punto que no sea Id, utilice el parámetro opcional "splitOn".
En su ejemplo, la consulta debería verse así:

SELECT
    -- DocumentNav Object Columns 
    dn.DocumentNavID AS "Id",
    dn.IssuerName,
    -- ... all other DocumentNav properties..
    -- Reason Object Columns
    dh.ReasonID AS "Id"
    dh.LastModifiedBy,
    dh.IsApproved,
    dh.Corrected
    -- ... all other Reason properties..
FROM PA.DocumentNavs dn WITH(NOLOCK)
    JOIN PA.NAVTypes nt WITH(NOLOCK)
        ON nt.NAVTypeID = dn.NavTypeID
    LEFT JOIN PA.DocumentsHistory dh WITH(NOLOCK)
        ON dh.DocumentID = dn.DocumentID
    LEFT JOIN PA.Analysts a WITH(NOLOCK)
        ON a.AnalystID = dh.LastModifiedBy
WHERE dn.DocumentNavID = @DocumentNavID

Necesita que sus objetos estén con el nombre de propiedad "Id" (DocumentNav & Reason)



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué