web-dev-qa-db-ja.com

EntityFrameworkモデルを複数のデータベースにまたがる作成

次のようなことをすることは有効ですか?

CREATE SYNONYM [dbo].[MyTable] FOR [AnotherDatabase].dbo.[MyTable]

次に、Entity Frameworkのedmxファイルを変更して、他のテーブルと同じようにこのオブジェクトを読み取りますか?

簡単なサンプルテストを行ったところ、選択と更新には問題なく機能しているようですが、これを行うべきではない理由があるかどうかを知りたいと思いました。

2番目のデータベースを指すedmxファイルを作成し、そこにエンティティを構築してから、定義をコピーして1番目のデータベースのedmxファイルに貼り付けることで、テーブル定義を取得しています。

[〜#〜]更新[〜#〜]

誰かが興味を持っているなら、私はedmxファイルを複数のデータベースにまたがらせるために私がしたことを書きました ここ 。同義語を生成し、edmxファイルをマージするためのスクリプトが含まれています。

29
Rachel

あなたがテストをしてそれがうまくいったなら、あなたはおそらく他の誰も知らない何かを示したでしょう。これまで、私は常にこのタイプの質問に答えていました。2つのデータベースで単一のモデルを使用することはできません(2番目のデータベースからテーブルを隠すビューに基づくいくつかのより醜い回避策があります)。今、私は2つの回避策を知っています。

このアプローチの唯一の欠点は、データベースからモデルを更新を実行すると、EDMXのSSDL部分に手動で加えられたすべての変更が常に失われることです。これは、EDMXを手動で開発するか(非常に大変な作業です)、データベースから更新するたびに変更を追加するツール/スクリプトを使用することを意味します。

11
Ladislav Mrnka

ビュー(および他のデータベースが別のサーバー上にある場合はリンクサーバー)を使用してこれを行うこともできます。これにより、2つの別々のedmxファイルを管理/マージする必要がなくなります。リンクサーバーでこれを使用して、別のサーバー上の2番目のデータベースからデータを読み取りましたが、いくつかの簡単なテストを実行して、更新/挿入/削除が可能かどうかを確認しました。

私は分散トランザクションの経験がないので、分散トランザクションに関連する情報は良い、悪い、または両方の少しかもしれません。2つのデータベースが同じサーバー上にある場合I [〜#〜]仮定[〜#〜]分散トランザクションは適用されなくなります。

リンクサーバーを使用する際に留意すべき点がいくつかあります。

  1. リンクされたデータベーステーブルのエンティティを変更し、コンテキストでSaveChangesを呼び出すと、分散トランザクションが開始されます。そのため、誰かがそれを停止する方法を知らない限り、2つのサーバーが次のように設定されていることを確認する必要があります。分散トランザクションを処理します。 (これは同義語を使用しても当てはまると思います)。
  2. リンクサーバー上のID列を持つエンティティへの挿入は、efがSCOPE_IDENTITY()を使用して新しいIDを取得しようとし、それがnullであるため、例外をスローします。これを回避する方法があるかどうかはわかりません。 ID列を持つリンクサーバー上のエンティティの更新または削除に問題はありませんでした。

SQL Server Aの場合

  1. serverBにリンクされたサーバーを作成します(dbが同じサーバー上にある場合はこれをスキップします)。
  2. アクセスしたい[ServerA].[MyDB]のテーブルごとに[ServerB].[AnotherDB]にビューを作成します

EDMXの場合

  1. ビューをedmxファイルに追加します
  2. デザイナの各プロパティ(実際のpkを含む)からエンティティキー設定をクリアします
  3. 実際のpkのエンティティキーをリセットします
  4. 必要に応じて関連付けを追加します
  5. 変更内容を保存

更新/挿入/削除の場合

  1. edmxファイルを右クリックして、xmlエディターで開きます
  2. StorageModel-> Schema-> EntityContainerに移動します
  3. エンティティのエンティティセットを見つけて、DefiningQuery要素を削除します
  4. エンティティセットでstore:Schema属性を見つけ、store:を削除してSchemaになるようにします。その値はそのままにしておきます。
  5. リンクサーバーからのビューごとに手順3と4を繰り返します。
  6. 変更内容を保存

リンクサーバーを使用すると分散トランザクションが作成されるため、ObjectContextが成功する前に、SaveChangesでいくつかのことを行う必要がありました。

ctx.Connection.Open();
ctx.ExecuteStoreCommand("set xact_abort on");
ctx.SaveChanges();
ctx.Connection.Close();

おそらく、カスタムObjectContextを作成し、SaveChangesをオーバーライドしてこのようなものを追加することができます。

2
Brian Cauthon

同義語を使用したこのトリックは、edmxファイルを操作しなくても、「コードファースト」アプローチで完全に機能することがわかりました。

あなたがしなければならない唯一のことは、DataContextのOnModelCreatingメソッドでクラスを適切なシノニムに「バインド」することです。

たとえば、テーブルPersonnel別のDB(およびクラス名もPersonnel)で、シノニムの名前が "myschema.MySynonym"の場合、OnModelCreatingメソッドは次のようになります。

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.HasDefaultSchema("myschema");

        modelBuilder.Entity<Personnel>()
            .ToTable("MySynonym");

        Database.SetInitializer<TestSynonymContext>(null);

        base.OnModelCreating(modelBuilder);
    }
1
ka3yc