splitOn Error al usar una relación de uno a muchos en dapper

asp.net dapper

Pregunta

Estoy intentando usar la función Multimapping de dapper para devolver una lista de categorías de menús y menús asociados. Pero estoy obteniendo el siguiente error: -

al utilizar las API de mapeo múltiple, asegúrese de configurar el parametro splitOn si tiene claves distintas de Id

Aquí están mis clases:

VMMenuCategory.cs

public class VMMenuCategory
    {
        public int MenuCategoryID { get; set; }
        public string CategoryName { get; set; }
        public System.DateTime CreatedOn { get; set; }
        public DateTime? UpdatedOn { get; set; }


        public List<VMMenu> Menus { get; set; }
    }

VMMenus.cs

 public class VMMenu
    {
        public int MenuID { get; set; }
        public int MenuCategoryID { get; set; }
        public string ProductName { get; set; }
        public int? CostPrice { get; set; }
        public int? SellingPrice { get; set; }
        public System.DateTime CreatedOn { get; set; }
        public DateTime? UpdatedOn { get; set; }

    }

MenuCategoriesRepository.cs

public sealed class MenuCategoryRepository : Connection, IMenuCategoryRepository
    {


        List<VMMenuCategory> IMenuCategoryRepository.GetAllMenuCategories()
        {
            List<VMMenuCategory> _lstVMMenuCategory = new List<VMMenuCategory>();
            string query = "select * from [dbo].[MenuCategories]";
            using (var connection = GetConnection())
            {
                var data = connection.Query<VMMenuCategory, VMMenu, VMMenuCategory>(query, map:(mc,m) => { mc.Menus =new List<VMMenu>() ;return mc; },splitOn: "MenuID").ToList();
                return data;
            }
            //return _lstVMMenuCategory;
        }
    }

Respuesta aceptada

Cambié mi método para completar datos jerárquicos.

A continuación está el código:

public sealed class MenuCategoryRepository : Connection, IMenuCategoryRepository
    {
        List<VMMenuCategory> IMenuCategoryRepository.GetAllMenuCategories()
        {
            List<VMMenuCategory> _lstVMMenuCategory = new List<VMMenuCategory>();
            string query = @"
            select mc.*, m.*
            from [dbo].[MenuCategories] mc
            join [dbo].[Menu] m on mc.MenuCategoryID = m.MenuCategoryID";
            using (var connection = GetConnection())
            {
                var vmMenuCategoryDictionary = new Dictionary<int, VMMenuCategory>();
                var data = connection.Query<VMMenuCategory, VMMenu, VMMenuCategory>(
                   query,
                   map: (mc, m) =>
                   {
                       VMMenuCategory _VMMenuCategory;
                       if(!vmMenuCategoryDictionary.TryGetValue(mc.MenuCategoryID,out _VMMenuCategory))
                       {
                           _VMMenuCategory = mc;
                           _VMMenuCategory.Menus = new List<VMMenu>();
                           vmMenuCategoryDictionary.Add(_VMMenuCategory.MenuCategoryID, _VMMenuCategory);

                       }
                       _VMMenuCategory.Menus.Add(m);                   
                       return _VMMenuCategory;
                   },
                   splitOn: "MenuID").Distinct().ToList();
                _lstVMMenuCategory = data;
            }
            return _lstVMMenuCategory;
        }
    }

Respuesta popular

Para llenar dos objetos con datos de dos tablas, debe consultar ambas tablas. En tu caso, lo más probable es una unión interna:

public sealed class MenuCategoryRepository : Connection, IMenuCategoryRepository
{
    List<VMMenuCategory> IMenuCategoryRepository.GetAllMenuCategories()
    {
        List<VMMenuCategory> _lstVMMenuCategory = new List<VMMenuCategory>();
        string query = @"
            select mc.*, m.*
            from [dbo].[MenuCategories] mc,
            join [dbo].[Menus] m on mc.MenuCategoryID = m.MenuCategoryID
        ";
        using (var connection = GetConnection())
        {
            var data = connection.Query<VMMenuCategory, VMMenu, VMMenuCategory>(
               query,
               map:(mc,m) => {
                   var foundMc = _lstVMMenuCategory
                       .FirstOrDefault(x => x.MenuCategoryID = mc.MenuCategoryID);
                   if (foundMc == null) {
                       foundMc = mc;
                       foundMc.Menus = new List<VMMenu>() ;
                   }
                   foundMc.Menus.Add(m);
                   return mc; 
               },
               splitOn: "MenuID").ToList();
        }
        return _lstVMMenuCategory;
    }
}

Nota: Adiviné el segundo nombre de la tabla y también asumí que MenuID es lo primero en la definición de la tabla Menus . Sin embargo, es mejor enumerar todas las columnas requeridas explícitamente en la cláusula de selección.

También modifiqué ligeramente la función del asignador para evitar duplicados en la colección de categorías.



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é