web-dev-qa-db-ja.com

複雑なオブジェクトのすべての親/子データをプルバックする方法

データベースには、1つ(カテゴリ)から多数(製品)の関係を持つ次の2つのテーブルがあります。

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つを結び付ける方法がわかりません。

単一の製品に対してそれを行う方法を知っていますが、個々のカテゴリオブジェクトを持つすべての製品についても同様です。

23
LRP

このようなテーブルがあると仮定します。

製品

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」パラメーターを使用します。

25
Shyju

これはあなたが望むことをするはずです:

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のプロパティの1つに選択した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();
7
Mauro Cerutti