如何使用.Net中的dapper ORM回退复杂对象中的所有父/子数据

时间:2013-12-20 19:12:40

标签: c# dapper multiple-resultsets

我有两个表在数据库中有一个(类别)到多个(产品)关系

Table Product
    Name
    Description
    ProductCategory

Table Category
    Category
    Description

这些课程;

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

我希望在列表中找到包含所有产品和类别对象数据的列表。我已经阅读了关于multipleResults和queryMultiple但是看不到如何将两者结合在一起。我知道如何为单个产品做到这一点但是所有具有各自类别对象的产品也是如此。

2 个答案:

答案 0 :(得分:24)

假设您有这样的表格。

<强>产品

ID
ProductName
ProductCategoryID

<强>分类

ID
CategoryName

和你的班级

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

以下代码可以很好地加载带有相关类别的产品列表。

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 注意: Dapper假设您的Id列被命名为“Id”或“id”,如果您的主键不同或者您想要在“Id”以外的点拆分宽行,使用可选的'splitOn'参数。

答案 1 :(得分:7)

这应该按照你的意愿行事:

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

此外,您为其中一个CategoryName属性选择的Product名称不方便。

我建议你改变你Product这样的课程:

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

然后查询可以变得更清洁:

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