Dapper: las API de mapeo múltiple aseguran que configure el splitOn
Para el código que se muestra a continuación, recibo el siguiente mensaje de error.
*** Error ***
Al usar las API de mapeo múltiple, asegúrese de configurar el parámetro splitOn si tiene claves que no sean Id (parámetro 'splitOn')
Por lo que entiendo, estoy pasando el parámetro splitOn. ¿Me estoy perdiendo algo obvio?
Código
using (var connection = new Microsoft.Data.SqlClient.SqlConnection(connectionString))
{
connection.Open();
LookupTables = connection.Query<LookupTable, List<LookupValue>, LookupTable>("exec [lookups].[SelAllLookupTable]",
(lookuptable, lookupvalue) => {
lookuptable.LookUpValues = lookupvalue.ToList<LookupValue>();
return lookuptable;
}, splitOn: "LookupValueID").ToList();
}
Actualizar
Código de proceso almacenado
ALTER PROCEDURE [lookups].[SelAllLookupTable]
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 lt.[LookupTableID],
lt.[GUID],
lt.[CreatedBy],
lt.[CreatedOn],
lt.[UpdatedBy],
lt.[UpdatedOn],
lt.[ChangeReason],
lt.[Name],
lt.[Description],
lv.[LookupValueID],
lv.[LookupTableID],
lv.[GUID],
lv.[CreatedBy],
lv.[CreatedOn],
lv.[UpdatedBy],
lv.[UpdatedOn],
lv.[ChangeReason],
lv.[Description],
lv.[DisplayOrderNo]
FROM lookups.LookupTable lt
LEFT JOIN lookups.LookupValue lv ON lt.LookupTableID = lv.LookupTableID
END
Respuestas
No tengo tus datos, pero creo que deberías cambiar tu código de esta manera.
// Where we store the distinct LookUpTable found by the query
Dictionary<int, LookUpTable> result = new Dictionary<int, LookUpTable>();
using (var connection = new Microsoft.Data.SqlClient.SqlConnection(connectionString))
{
connection.Open();
var LookupTables = connection.Query<LookupTable, LookUpValue, LookupTable>("exec [lookups].[SelAllLookupTable]",
(lkt, lkv) =>
{
// Check if we have the instance already in the dictionary
// add it if not,
if (!result.ContainsKey(lkt.LookUpTableID))
result.Add(lkt.LookUpTableID, lkt);
result[lkt.LookupTableID].LookUpValues.Add(lkv);
return lkt;
}, splitOn: "LookupValueID").ToList();
}
return result.Values.ToList();
Dapper no creará ni pasará una lista de LookUpValue directamente, pero iterará sobre los registros creando los objetos de cada registro devuelto y pasando estos objetos uno por uno a la expresión lambda.
Su expresión lambda podría usar un diccionario para almacenar cada objeto LookupTable recibido y agregar el objeto LookupValue a su propiedad. Cuando Dapper finaliza su iteración sobre el registro, sus objetos se almacenan en la colección de valores del diccionario.
Por supuesto, esto supone que su clase LookUpTable tiene una List<LookUpValue>propiedad
public class LookupTable
{
public int LookupValueID { get; set; }
.... other properties ....
public List<LookUpValue> LookUpValues {get;set} = new List<LookUpValue>();
}
Observe cómo la propiedad crea la lista en la inicialización para evitar una lógica compleja en la expresión Dapper lambda.