Multi Mapping en Dapper. Recibiendo el error en SpiltOn

dapper multimap

Pregunta

* ¿Puedes explicar la función Split on en el multimap *

Estoy intentando obtener los datos de la base de datos usando Dapper ORM. He recibido el siguiente error System.ArgumentException: Al usar las API de mapeo múltiple, asegúrese de configurar el parametro splitOn si tiene claves que no sean Id. Nombre del parámetro: splitOn

 public abstract class Domain
    {
       public Guid Id { get; set; }
    }


public abstract class ItemBase : Domain
  {
     private IList<Image> images = new List<Image>();
     public Guid? ParentId { get; set; }
     public string Name { get; set; }
     public IList<Image> Images { get { return images; } }
  }

 public class Meal : ItemBase
   {

   }

public class Item : ItemBase
  {
     private IList<Meal> meals = new List<Meal>();
     public IList<Meal> Meals { get { return meals; } };
  }


public class Image : Domain
  {
      public byte Img { get; set; }
       public string Description { get; set; }
   }



 public  class MealImageLink : Domain
 {
     public Guid ItemId { get; set; }
     public Guid ImageId { get; set; }
 }

/ * función de búsqueda para tomar dat de la tabla * /

private List<Meal> SearchMeals(Guid id)
 {
   var query = @"SELECT meal.[Name],meal.[Description],meal.

   [Price],mealImage.[Image] as Img    
                                  FROM      [MealItems] as meal  
                                  LEFT JOIN   [MealImageLink] mealImageLink 

  on meal.Id= mealImageLink.MealItemId
                                  LEFT JOIN   [Images] mealImage on  

   mealImageLink.ImageId=mealImage.Id
                                  WHERE  meal.[ParentId]=@Id";

List<Meal> meals = ( _connection.Query<Meal, MealImageLink, Image, Meal>
                                       (query, (meal, mealLink, mealImage) =>
                                       {
                                           meal.Images.Add(mealImage);
                                           return meal;
                                       }, new { @Id = id })).ToList();
return meals;
}

Respuesta experta

La función de múltiples mapas es realmente más adecuada para escenarios como:

select foo.Id, foo.whatever, ...,
       bar.Id, bar.something, ...,
       blap.Id, blap.yada, ...
from foo ...
inner join bar ...
left outer join blap ...

o el más perezoso pero no poco común:

select foo.*, bar.*, blap.*
from ...
inner join bar ...
left outer join blap ...

Pero en ambos casos, hay una manera clara y obvia de dividir el rango horizontal en particiones; básicamente, cada vez que veas una columna llamada Id , es el siguiente bloque. El nombre Id se puede configurar por conveniencia, y puede ser una lista delimitada de columnas para escenarios donde cada tabla tiene un nombre de clave primaria diferente (para que el User pueda tener UserId , etc.).

Tu escenario parece bastante diferente a esto. Parece que actualmente solo selecciona 4 columnas sin una forma particular de dividirlas. Sugeriría que en este caso , es más fácil poblar su modelo a través de una API diferente, en particular, la API dynamic :

var meals = new List<Meal>();
foreach(var row in _connection.Query(sql, new { @Id = id }))
{
    string name = row.Name, description = row.Description;
    decimal price = row.Price;
    // etc

    Meal meal = // TODO: build a new Meal object from those pieces
    meals.Add(meal);
}

La API dynamic se accede simplemente al no especificar ningún <...> . Una vez hecho esto, se accede a las columnas por nombre, con sus tipos implicados por lo que se les asigna , por lo tanto, cosas como:

decimal price = row.Price;

Nota: si desea consumir los datos de la row "en línea", simplemente envíe lo más pronto posible , es decir,

// bad: forces everything to use dynamic for too long
new Meal(row.Name, row.Description, row.Price);

// good: types are nailed down immediately
new Meal((string)row.Name, (string)row.Description, (decimal)row.Price);

¿Eso ayuda?

Tl; dr: Simplemente no creo que el mapeo múltiple sea relevante para su consulta.


Editar: esta es mi mejor estimación sobre lo que pretendes hacer, simplemente no es una buena opción para multi-mapa:

var meals = new List<Meal>();
foreach (var row in _connection.Query(query, new { @Id = id })) {
    meals.Add(new Meal {
        Name = (string)row.Name,
        Images = {
            new Image {
                Description = (string)row.Description,
                Img = (byte)row.Img
            }
        }
    });
}
return meals;


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é