1

Store複数の s を持つことができるなど、複数の子を持つことができる親ドキュメントがある場合、ドキュメントProductにリストを保存する簡単な方法はありますか? Product.IdStore

現在、最初にオブジェクトを保存しProductてから、それらをループしてProduct.IdforStore.ProductIdsプロパティを取得しています。

class Store
{
    public string Id { get; set; }
    public string Name { get; set; }
    public IList<string> ProductIds { get; set; }
    [JsonIgnore]        
    public IList<Product> Products { get; set; }
}

製品

class Product
{
    public string Id { get; set; }
    public string Name { get; set; }
}

現在の作業中の保存方法

var store = new Store()
{
     Name = "Walmart",
     Products = new List<Product>
                    {
                        new Product {Name = "Ball"},
                        new Product {Name = "Bat"}
                    }
};

using (var session = DocumentStore.OpenSession())
{
    foreach (var product in store.Products)
    {
        session.Store(product);
    }

    session.SaveChanges();

    var list = new List<string>();

    foreach (var product in store.Products)
    {
        list.Add(product.Id);
    }

    store.ProductIds = list;

    session.Store(store);
    session.SaveChanges();
}
4

1 に答える 1

2

特定の質問に答えるには、コードで単純化できることが 2 つあります。

  • 最初session.SaveChanges(); の製品 ID は、製品を呼び出したときに作成されます.Store()

  • 製品 ID をいくつかの linq で収集して、1 行に折りたたむことができます。

    store.ProductIds = store.Products.Select(x=> x.Id).ToList();

ただし、一般的なアプローチは同じですが、コードを少し単純化しただけです。

このアプローチは機能しますが、便宜上製品をストアに配置しているだけであることを認識してください。 [JsonIgnore]ここでは問題ありませんが、シリアライゼーションにのみ役立ちます - デシリアライゼーションには役立ちません。つまり、ストアをロードするときに、ProductIds リストのみが入力されます。それらを別々にロードする必要があります(おそらくを使用して.Include()

個人的にProductsは、Store オブジェクトからリストを完全に削除します。Entity Framework や NHibernate などの他のリレーショナル製品は、この目的のために仮想メンバーとプロキシ クラスを使用しますが、RavenDB ではほとんど意味がありません。クラスのコンシューマーは、プロパティが無視されていることを認識しないため、その使用法を誤解する可能性があります。Productsプロパティを見ると、それぞれがドキュメントに完全に埋め込まれていることが期待されます。その場合、個別のリストProductは必要ありません。ProductIds両方を無視すると、混乱が生じるだけです。

提案された設計に対するもう 1 つの反論は、すべての店舗のすべての製品が暗黙のうちに一意になるということです。これは、ストアを使用して製品を作成し、それぞれを個別に追加しているためです。実際にすべての製品が一意である場合 (「ボール」だけでなく「この特定のボール」)、[JsonIgnore]またはリストなしで製品を埋め込むことができ、 が として存在するProductIds必要はありません。Product別のドキュメント。製品が一意ではない (複数の店舗でバットとボールを販売できる) 可能性が高いシナリオでは、次の 2 つのオプションがあります。

class Store
{
    public string Id { get; set; }
    public string Name { get; set; }
    public IList<string> ProductIds { get; set; }
}

class Store
{
    public string Id { get; set; }
    public string Name { get; set; }
    public IList<Product> Products { get; set; }
}

Productいずれの場合でも独自のドキュメントに含まれます。2 番目のシナリオは非正規化された参照として使用されるため、製品をロードせずに製品名を取得できます。これは問題ありませんが、製品名が変更される可能性がある場合は、多くのパッチを適用する必要があります。

「こうすればいい」という明確な答えがない場合は申し訳ありません。Raven には多くのオプションがあり、さまざまな使用方法に応じて、いずれかの方法がより適切に機能する場合があります。個人的には、ProductIds のリストを保持するだけです。関連ドキュメントをいつでも索引付けして、照会目的で製品名を引き出すことができます。

于 2013-02-06T21:38:34.357 に答える