1

これは非常に奇妙なアーキテクチャです。我慢してください。

既存の階層型アプリケーション (データ、ロジック/サービス、クライアント) があります。最新の要件は、サービス レイヤーが 2 つのデータ ソースにアクセスすることです!!!! (他の方法はありません) これら 2 つのデータ ソースには同じ DB スキーマがあります。

ほとんどの階層型アーキテクチャと同様に、次のような読み取りおよび書き込みメソッドがあります。

IEnumerable<Product> GetAllProducts(),
Product GetProductById(ProductKey id),
IEnumerable<Product> FindProductsByName(string name)

製品の DTO は次のとおりです。

class Product
{
    public ProductKey Key { get; set;}
    ...
}

class ProductKey
{
    public long ID { get; }
}

考えられる解決策を 2 つに絞り込みました。

代替案 1: パラメーターを読み取りメソッドに追加して、サービスが使用する DB を次のように認識できるようにします。 Product GetProductById(ProductKey id, DataSource dataSource) DataSourceは列挙型です。

代替案 2 (私の解決策): DataSource プロパティをキー クラスに追加します。これは、オブジェクトの取得時に Entity Framework によって設定されます。また、これはデータベースに永続化されません。

class ProductKey
{
    public long ID { get; }
    public DataSource Source { get; } //enum
}

利点は、変更によるクライアントへの影響が最小限になることです。

ただし、人々はこのソリューションを好まないため、

  • これDataSourceはビジネス価値を追加しません。(私の回答は、IDビジネス価値も追加しないというものです。これは代理キーです。その目的は永続性を追跡することです)
  • DataSourceオブジェクト グラフの子には、冗長なものも含まれます

どちらのソリューションがより健全ですか? 他の選択肢はありますか?

注: これらのサービスはどこでも使用されています。

4

1 に答える 1

4

私が提案するのはドア番号3です。

[||||||||||||||]
[|||||||||s!   ]
[||||nerics!   ]
[  Generics!   ]

私は「動的リポジトリ」を使用しています (または、少なくとも私はそう呼んでいます)。同じ using ブロックにいながら (つまり、再インスタンス化せずに)、任意のデータコンテキストまたは dbset に接続できるように設定されています。

これが私がそれをどのように使用するかのスニペットです:

            using (var dr = new DynamicRepo())
            {
                dr.Add<House>(model.House);
                foreach (var rs in model.Rooms)
                {
                    rs.HouseId = model.House.HouseId;
                    dr.Add<Room>(rs);
                }
            }

これは、定義されている「デフォルト」の dbcontext を使用します。それぞれがリポジトリで定義されている必要がありますが、インスタンス化されていません。私が使用するコンストラクタは次のとおりです。

    public DynamicRepo(bool Main = true, bool Archive = false)
    {
        if (Main)
        {
            this.context = new MainDbContext();
        }
        if (Archive)
        {
            this.context = new ArchiveDbContext();
        }
    }

これは、コンテキストが 2 つしかない単純化されたバージョンです。使用するコンテキストを選択するために、より詳細な選択方法を実装できます。

初期化が完了すると、Add の動作は次のようになります。

    public void Add<T>(T te) where T : class
    {
        DbSet<T> dbSet = context.Set<T>();
        dbSet.Add(te);
        context.SaveChanges();
    }

これの優れた利点は、データベースと対話するためのコードを維持する場所が 1 つしかないことです。他のすべてのロジックは、さまざまなクラスに抽象化できます。この方法で汎用リポジトリを使用することで、間違いなく多くの時間を節約できました - 最初に変更に時間を費やしたとしても。

あなたが探していたものを誤解していないことを願っていますが、複数のデータ ソースに対して 1 つのリポジトリを使用しようとしている場合、これは良いアプローチだと思います。

于 2012-06-13T23:20:07.553 に答える