How to pull back all parent/child data in complex object

Assume you have your tables like this.

Product

ID
ProductName
ProductCategoryID

Category

ID
CategoryName

and your classes

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; }
}

The below code should work fine for you to load a list of products with associated categories.

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 hereNote : Dapper assumes your Id columns are named "Id" or "id", if your primary key is different or you would like to split the wide row at point other than "Id", use the optional 'splitOn' parameter.


This should do what you wish:

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();

Also, the CategoryName name you chose for one of the Product's properties is inconvenient.

I suggest you change you Product class like this:

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

Then the query can become cleaner:

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();