EFをORMとして使用するアプリケーションがあります。以前はデータベースに1つのスキーマdboがあり、すべて正常に機能していました。最近、テーブルを4つの異なるスキーマに編成しました。 1つのスキーマの一部のテーブルは、異なるスキーマにあるテーブルに依存しています。すべてはSQL側で有効なようです。
アプリ側では、EFを介したすべてのdbインタラクションが機能しなくなりました。コードがコンパイルされ、スキーマがソリューションに表示され、モデルマッピングが適切なスキーマを指しますが、テーブルに行を挿入しようとすると機能しません。
複数のスキーマを使用することに関する複数の投稿を見てきましたが、複数のDBContextを使用する必要がありますが、1つのDBContextを使用します。すべてのスキーマの所有者dboが同じであり、複数のDBContextを使用する理由がわかりません。
これを達成する方法があるかどうか誰もが知っていますか?
Fluentマッピングのみで、各テーブルを独自のスキーマにマッピングできます。 DbContext
サブタイプでは、OnModelCreating
をオーバーライドして(まだ行っていない場合)、次のようなステートメントを追加する必要があります。
modelBuilder.Entity<Department>()
.ToTable("t_Department", "school");
このように明示的にマッピングしないエンティティは、デフォルトのdbo
スキーマに配置されます。または、独自のデフォルトを提供できます
modelBuilder.HasDefaultSchema("sales");
( here から要約)
Gert Arnoldの応答に加えて、エンティティでTable属性を使用することもできます。
using System.ComponentModel.DataAnnotations.Schema;
[Table("t_Department", Schema = "school")]
public class Department
{
public int Id { get; set; }
public string Name { get; set; }
}
@GertArnoldは、彼の答えにスポットを当てています。ただし、純粋な構文キャンディーの場合は、モデルの名前空間からスキーマをプルする規則を介してこれを行うこともできます。これは複数のスキーマを扱うのに便利だとわかりました
modelBuilder.Types().Configure(e => {
var schema = e.ClrType.Namespace.Split('.').Last().ToLower();
var name = entity.ClrType.Name;
return entity.ToTable(name, schema);
});
上記は、名前空間の最終コンポーネントを取得し、それをスキーマ名として使用します。これにより、すべてのエンティティのテーブルバインディングをカスタマイズする必要がなくなります。
クラスヘッダーなどのスキーマを配置しますが、そのスキーマをどこに定義しますか?例えば:
[Table("Test", Schema = "test1")]
public class Test
{
public int Id { get; set; }
}
[Table("Test2", Schema = "test2")]
public class Test2
{
public int Id { get; set; }
}
しかし、どこにtest1とtest2を配置しますか?異なるDbContextまたはどこですか?