12

「製品」と「販売者」の 2 つのクラスがあります。

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }

    public Seller Seller { get; set; }
    public int? SellerId { get; set; }
}
public class Seller
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<Product> Products { get; set; }
}

dapper を使用して、すべての製品を含む販売者のリストを抽出したいと考えています。

現在、私はこのようにやっています:

Dictionary<int, Seller> dic = new Dictionary<int, Seller>();
        Conn.Query<Seller, Product, int>
            (@"select s.*,p.* from Sellers s Join Products p 
                on p.SellerId = s.Id",
            (s, p) => {
                if (dic.ContainsKey(s.Id))
                    dic[s.Id].Products.Add(p);
                else
                {
                    s.Products = new List<Product>();
                    s.Products.Add(p);
                    dic.Add(s.Id, s);
                }
                return s.Id; 
            });
        var sellers = dic.Select(pair => pair.Value);

もっと良い方法はありますか?

4

2 に答える 2

3

データの保存方法と使用方法を混在させていると思います。データベースを正規化することをお勧めします。

//Normalized Database classes
public class Seller
{
    public int Id { get; set; }  // primary key
    public string Name { get; set; }
}

public class Product
{
    public int Id { get; set; }  // primary key
    public int SellerId { get; set; } // foreign key
    public string Name { get; set; }
    public decimal Price { get; set; }
}

次に、Seller テーブルと product テーブルを直接クエリできます。

var Sellers = connection.Query<Seller>("Select * from Seller");
var Products = connection.Query<Product>("Select * from Product");

次に、linq "group by" を使用して Product をディクショナリにスローします

var SellerWithProductsDict = 
        (from prod
        in Products 
        group prod by prod.SellerId
        into groupedProducts
        select groupedProducts)
        .ToDictionary(gp => gp.SellerId, gp => gp.ToList());

次に、SellerWithProductsDict をループしてすべての販売者の製品を表示し、販売者の名前が必要な場合は、Sellers クエリの結果からインデックスで取得します。

******************************************

これで答えは終わりですが、売り手と製品を混在させる必要がある場合は、上記と同じデータベース構造を使用して、次のようにすることができます。

var qry = @"Select s.Id as SellerId,
                   s.Name as SellerName,
                   p.Id as ProductId,
                   p.Name as ProductName,
                   p.Price as ProductPrice
            From Seller as s, Product as p
            Where s.Id = p.id"

var SellerWithProducts = connection.Query(qry)

次に、linq の「グループ化」関数を使用して、それを辞書に投入します。group by linq のヘルプについては、この「 Linq group-by multiple fields 」の投稿を参照することをお勧めします。

于 2012-11-13T06:02:40.740 に答える
1

前回の投稿がなぜかおかしくなりました。

まず、データベースからすべてを取得するのは悪い考えかもしれません。クエリを制限することを検討してください。今はテーブルが小さいかもしれませんが、壁に背を向けたくはありません。

そうは言っても、Seller と Product に静的メソッドを追加して、Sellers と Products を取得するコードを簡素化することをお勧めします。

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }

    public int? SellerId { get; set; }
    public Seller Seller { get; set; }

    public static Product GetProductById(int id)
    {
        Product product = null;
        using (SqlConnection connection = new SqlConnection("connectionString"))
        {
            product = connection.Query<Product>("select * from Product where Id = @Id", new { Id = id }).SingleOrDefault();
            product.Seller = connection.Query<Seller>("select * from Seller where Id = @Id", new { Id = product.SellerId }).SingleOrDefault();
        }

        return product;
    }
}

public class Seller
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<Product> Products { get; set; }

    public static Seller GetSellerById(int id)
    {
        Seller seller = null;
        using (SqlConnection connection = new SqlConnection("connectionString"))
        {
            seller = connection.Query<Seller>("select * from Seller where Id = @Id", new { Id = id }).SingleOrDefault();
            if(seller != null)
            {
                seller.Products = connection.Query<Product>("select * from Product where SellerId = @Id", new { Id = id }).ToList();
                seller.Products.ForEach(p => p.Seller = seller);
            }
        }

        return seller;
    }
}

これは大まかなものであり、必要なすべてを表しているわけではありませんが、長期的には使いやすく、データを取得するためにクエリを作成するよりもオブジェクト指向設計に準拠していることに注意してください。

GetSellersInZipCode(int zipCode) のような売り手または製品に関する他のことをクエリし、そのメソッドを介して List を返すメソッドを追加することで、このアイデアをさらに拡張できます。

于 2012-11-09T21:54:05.707 に答える