大まかなドットネットormと1対多の関係を抽出する最良の方法は?

c# dapper one-to-many orm

質問

私は2つのクラス 'Product'と 'Seller'を持っています。

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

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

受け入れられた回答

私はあなたがデータをどのように使用したいのかとどのように保存するかをミックスしていると思います。あなたのデータベースを正規化することをお勧めします。

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

次に、売り手テーブルと商品テーブルを直接照会することができます。

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をループしてすべての売り手の商品を見ることができます。売り手の名前が必要な場合は、売り手の検索結果からインデックスを取得するだけです

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

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

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 group-by複数のフィールド "を見て、linqによるグループの助けを求めるポストを提案します


人気のある回答

私の最後の投稿は何らかの理由で狂ってしまった。

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

そう言えば、売り手と商品に静的メソッドを追加することで、売り手と商品を入手するコードを単純化することをお勧めします。

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を返すメソッドを追加することで、このアイデアをさらに拡大できます。



ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ