Cómo recuperar todos los datos principales / secundarios en objetos complejos usando dapper ORM en .Net

c# dapper multiple-resultsets

Pregunta

Tengo estas dos tablas con una relación de una (categoría) a muchas (producto) en la base de datos

Table Product
    Name
    Description
    ProductCategory

Table Category
    Category
    Description

Y estas clases;

public class Product
{
  public string Name { get; set; }
  public string Description { get; set; }
  public Category CategoryName { get; set}    
}


public class Category
{
  public string CategoryName { get; set; }
  public string Description { get; set; }    
}

Quiero obtener una lista con todos los datos de objeto de categoría y producto en una lista. He leído sobre multipleResults y queryMultiple, pero no veo cómo vincular los dos. Sé cómo hacerlo para un único producto, pero también todos los productos con sus objetos de categoría individuales.

Respuesta aceptada

Supongamos que tiene sus tablas como esta.

Producto

ID
ProductName
ProductCategoryID

Categoría

ID
CategoryName

y tus clases

public class Product
{
    public int ID { set; get; }
    public string ProductName { set; get; }
    public int ProductCategoryID  {set;get;}
    public Category Category { set; get; }
}
public class Category
{
    public int ID { set; get; }
    public string CategoryName { set; get; }
}

El siguiente código debería funcionar bien para que cargue una lista de productos con categorías asociadas.

var conString="Replace your connection string here";
using (var conn =   new SqlConnection(conString))
{
    conn.Open();
    string qry = "SELECT P.ID,P.ProductName,P.ProductCategoryID,C.ID,
                  C.CategoryName from Product P  INNER JOIN   
                  Category C ON P.ProductCategoryID=C.ID";
    var products = conn.Query<Product, Category, Product>
                     (qry, (prod, cat) => { prod.Category = cat; return prod; });

    foreach (Product product in products)
    {
        //do something with the products now as you like.
    }
    conn.Close(); 
}

enter image description here Nota: Dapper supone que sus columnas Id se llaman "Id" o "id", si su clave principal es diferente o si desea dividir la fila ancha en un punto que no sea "Id", utilice el parámetro opcional "splitOn".


Respuesta popular

Esto debería hacer lo que desees:

var res = db.Query<Product, Category, Product>(
  @"select p.[Name], p.[Description], c.Category, c.Category as [CategoryName], c.Description
  from Product p
  inner join Category c on c.Category = p.ProductCategory",
  (prd, cat) => {
      prd.CategoryName = cat;
      return prd;
  },
  splitOn: "Category"
  ).AsQueryable();

Además, el nombre de CategoryName que eligió para una de las propiedades del Product es inconveniente.

Te sugiero que cambies tu clase de Product esta manera:

public class Product
{
   public string Name { get; set; }
   public string Description { get; set; }
   public Category Category { get; set; }    
}

Entonces la consulta puede ser más clara:

var res = db.Query<Product, Category, Product>(
    @"select p.[Name], p.[Description], c.Category as [CategoryName], c.Description
      from Product p
      inner join Category c on c.Category = p.ProductCategory",
      (prd, cat) => {
          prd.Category = cat;
          return prd;
      },
      splitOn: "CategoryName"
      ).AsQueryable();


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é