1

オブジェクトを格納するために、db4o データベースの周りに素敵なリポジトリ レイヤーを構築しました。オブジェクトは、1 対多の関係でオブジェクトにProduct関連付けられManufacturerます。

public class Manufacturer
{
    public string Name { get; set; }
}

public class Product // simplified
{
    public string Name { get; set; }
    Manufacturer Manufacturer { get; set; }
}

これまでのところ、私は db4o が本当に好きです。私が抱えている問題は、ID に頼らずにデータの重複を防ぐことです。

SQL Server を使用してメーカーなどの参照を実装すると、データ モデルに一意の ID フィールドが含まれ、クラスがManufacturerIDProductで汚れてしまいます。db4o のようなオブジェクト データベースを使用すると、リレーショナル DB とオブジェクト間のインピーダンスの不一致が減少するのではないかと想像しましたが、ID がないと、オブジェクトを編集するときにオブジェクトを別のオブジェクトと区別する方法がありません。

データを複製せずに製品間でメーカーを共有するエレガントな方法はありますか? それとも、リレーショナル DB を使用する必要がありますか?

4

3 に答える 3

1

まずは基本的なこと。db4o はobject-identityによってオブジェクトを管理します。同じオブジェクト インスタンスを再度保存すると、db4o はデータベース内のそのオブジェクトを更新します。参考文献も同様です。2 つの異なるオブジェクトが同じオブジェクトを参照する場合、それらは実際にはデータベース内の同じオブジェクトを参照します。あなたの例では: 2 つの異なる製品が同じ製造元インスタンスを参照する場合、それらはデータベース内の同じ製造元も参照します。これは、オブジェクトを追跡するバックグラウンドにテーブルを配置することによって実現されます。

現在、このアプローチには問題があります。オブジェクト (Web アプリケーション、Web サービスなど) をシリアル化するか、オブジェクト コンテナーを閉じるとすぐに、db4o はメモリ内のどのオブジェクトがどのオブジェクトに属しているかを忘れてしまいます。次に、既存のオブジェクトを認識せず、単に新しいオブジェクトとして保存します。これは、異なるオブジェクト コンテナー インスタンスを持つオブジェクトを読み込んで格納してはならないことを意味します。また、オブジェクトを認識するために ID が必要になることもあります。たとえば、Web リクエスト全体でオブジェクトを認識します。簡単な解決策は、Guid を使用してオブジェクトに一意の ID を与えることです。

質問に戻ります。製品間でメーカーを共有するには、同じメーカーを指すだけです。このような:

Product newShinyProduct = new Product(); // the new thing
// Get a existing product or manufacturerer, doesn't matter
Product oldProduct = (from p in container.AsQueryable<Product>()
                     where p.Name == "Get a product"
                     select p).First();

// now just assigne the existing manufacturer to the new product
// this product will now refer to the same manufacturer
// and db4o will store this that way. The manufacturer isn't doublicated.
newShinyProduct.Manufacturer = oldProduct.Manufacturer;
// store the new product in the database.
container.Store(newShinyProduct);
于 2011-03-14T22:04:39.947 に答える
1

構成で db4o に一意のインデックスを追加できます。

configuration.Common.ObjectClass(typeof (Manufacturer)).ObjectField("<Name>k__BackingField").Indexed(true);
configuration.Add(new UniqueFieldValueConstraint(typeof(Manufacturer), "<Name>k__BackingField"));

このようにして、データベースに同じ名前の 2 つの異なる製造元オブジェクトを含めることはできません。自動プロパティを使用しているため、フィールド名は「k__BackingField」にする必要があります。もちろん、整数 ID を追加して、同じ方法でインデックスを作成することもできます。

于 2011-03-14T22:05:34.050 に答える
0

db4o は、格納された各オブジェクトに対して固有の内部 ID を維持します。

次のリンクを確認してください: http://community.versant.com/documentation/reference/db4o-8.1/java/reference/Content/basics/identity_concept.htm

http://community.versant.com/documentation/reference/db4o-8.1/java/reference/Content/platform_specific_issues/disconnected_objects/comparison_of_ids.htm

于 2012-09-28T11:59:46.450 に答える