0

私はいくつかのグーグルをしましたが、私はまだ解決策を見つけていません、あるいは私の問題に対する決定的な答えさえ見つけていません。

問題は単純です。動的に名前が付けられた/作成されたオブジェクトのインスタンスごとにテーブルを動的に作成したいと思います。各テーブルには、オブジェクトに固有のレコードが含まれます。これは本質的にアンチパターンであることを認識していますが、これらのテーブルは理論的には非常に大きくなる可能性があるため、すべてのデータを1つのテーブルに含めるとパフォーマンスの問題が発生する可能性があります。

より具体的な例:

トランザクションのコレクションを含む基本クラス/インターフェースACCOUNTがあります。私のソフトウェアを使用する会社ごとに、クラスの新しい具体的なバージョン、BOBS_SUB_SHOP_ACCOUNTまたはSAMS_GARAGE_ACCOUNTなどを作成します。したがって、クラスの識別値はクラス名であり、クラス内のフィールドではありません。

私はC#とFluentnHibernateを使用しています。

だから私の質問は:

  1. これは理にかなっていますか、それとももっと明確にする必要がありますか?(または、本当にしてはいけないことをしようとしていますか?)
  2. このパターンには名前がありますか?
  3. nHibernateはこれをサポートしていますか?
  4. 私が読むことができるパターンに関するドキュメントを知っていますか?

編集:これについてもう少し考えてみたところ、動的オブジェクトは本当に必要ないことに気づきました。必要なのは、NHibernateを介して何らかの識別子を持つオブジェクトをテーブルに結び付ける方法です。例えば:

//begin - just a brain dump
public class Account
{
  public virtual string AccountName { get; set; }
  public virtual IList Stuff { get; set; }
}

... somewhere else in code ...

//gets mapped to a table BobsGarageAccount (or something similar)
var BobsGarage = new Account{AccountName="BobsGarage"}; 
//gets mapped to a table StevesSubShop(or something similar)
var StevesSubShop = new Account{AccountName="StevesSubShop"};
//end

NHibernateがそれを許可すると仮定すると、それは私が必要とするものには十分なはずです。アカウントテーブルで大量のボリュームが発生した場合に、1つの巨大なテーブルがそれを打ち負かすような状況を回避しようとしています。すべてのアカウントが1つのテーブルにある場合、それは醜い可能性があります。

前もって感謝します。

4

2 に答える 2

1

その場でクラスを作成するのではなく、動的オブジェクトをお勧めします。適切なインターフェイスを実装する場合(1つの例はここにあり、いずれの場合もから継承することでそこに到達できますDynamicObject)、次のように記述できます。

dynamic bobsSubShopAccount = new DynamicAccount("BOBS_SUB_SHOP_ACCOUNT");
Console.WriteLine("Balance = {0}", bobsSubShopAccount.Balance);

クライアントコードで。DLRを使用して実装する場合DynamicAccount、これらの呼び出しはすべて実行時にインターセプトされ、実行時にクラスに渡されます。だから、あなたは方法を持つことができます

public override bool TryGetMember(GetMemberBinder binder, out object result)
{
    if (DatabaseConnection.TryGetField(binder.Name, out result))
        return true;

    // Log the database failure here

    result = null;
    return false; // The attempt to get the member fails at runtime
}

クライアントコードによって要求されたメンバーの名前を使用してデータベースからデータを読み取る。

私はNHibernateを使用したことがないので、NHibernateが動的オブジェクトをどのように処理するかについて権限を持ってコメントすることはできません。

于 2012-02-09T23:01:41.580 に答える
0

これらのクラスは私にはひどく臭いように見え、ドメインの問題ではなく、実際のストレージレイヤーの問題に相当するものを解決しようとします。シャーディングは、本質的にあなたが探している用語です。

dbのパフォーマンスが本当に心配で、負荷が非常に大きくなる場合は、代わりにテーブルをパーティション化することを検討してください。ドメインオブジェクトはパーティションキーの作成を簡単に処理でき、NHibernateでクレイジーなブードゥーを行う必要はありません。これにより、後で永続化メカニズムを変更した場合に備えて、ドメインレベルの問題を簡単に実行できなくなります。マップにコレクションフィルターを作成するか、読み取り専用オブジェクトをビューにマップできます。ただし、後者のオプションは、ドメイン内では少し臭いです。

ブードゥーを行うことを絶対に主張する場合は、NHibernate.Shardsを確認することをお勧めします。これは、データベースのシャーディングを簡単にすることを目的としています。現在の開発状況と互換性については言えませんが、それはオプションです。

于 2012-02-10T03:17:58.763 に答える