19

単一の Oracle データベースで複数のスキーマを処理できるように dbContext を設定しようとしています。モノリシックな dbContext ファイルは 1 つも必要なかったので、次のように考えました。

public class oraDbContext : DbContext
{
    static oraDbContext() {
        Database.SetInitializer<oraDbContext>(null);
    }

    public oraDbContext(string connName)
        : base("Name=" + connName) { }

    public _schema1 schema1 = _schema1.Instance;
    public _schema2 schema2 = _schema2.Instance;

    protected override void OnModelCreating(DbModelBuilder modelBuilder) {
        schema1.OnModelCreating(modelBuilder);
        schema2.OnModelCreating(modelBuilder);
    }
}

スキーマ ファイルは次のようになります。

public sealed class _schema1
{
    private static readonly _schema1 instance = new _schema1();

    static _schema1() { }
    private _schema1() { }

    public static _schema1 Instance {
        get {
            return instance;
        }
    }

    public DbSet<someTable> someTable { get; set; }

    internal void OnModelCreating(DbModelBuilder modelBuilder) {
        modelBuilder.Configurations.Add(new someTableMap());
    }
}

ただし、クエリを実行しようとすると、次のエラーが表示されますValue cannot be null。参照している値は、someTable_schema1 のプロパティです。

A.どうすれば修正できますか?

B.より良い解決策はありますか?

編集:ここで欲しいのは、次のようなコードを書く能力です-

var query1 = from p in db.schema1.someTable
             select p;
var query2 = from p in db.schema2.someTable
             select p;

someTable は両方のスキーマで同じです。私たちのデータベースには、同一またはほぼ同一の列を持つまったく同じテーブルを持つスキーマがいくつかあります。5 つのスキーマからプルするクエリを作成している場合、5 つの異なる接続を意味する可能性があるため、スキーマごとに個別の dbContext を作成したくありません。この同じクエリを単純な SQL で記述していた場合、1 つの接続で 5 つの異なるスキーマからデータを取得できます。これが、ここで達成したいことです。

4

3 に答える 3

13

Entity Framework について調査しているときに、次の投稿に出くわしました。

http://romiller.com/2011/05/23/ef-4-1-multi-tenant-with-code-first/

動作する単一の dbContext を完全に提供するわけではありませんが、単一の接続のみを使用します (これは、複数の dbContext を使用したくないという私の理由でした)。次のコードを設定した後:

public class oraDbContext : DbContext
{
    static oraDbContext() {
        Database.SetInitializer<oraDbContext>(null);
    }

    private oraDbContext(DbConnection connection, DbCompiledModel model)
        : base(connection, model, contextOwnsConnection: false) { }

    public DbSet<SomeTable1> SomeTable1 { get; set; }
    public DbSet<SomeTable2> SomeTable2 { get; set; }

    private static ConcurrentDictionary<Tuple<string, string>, DbCompiledModel> modelCache = new ConcurrentDictionary<Tuple<string, string>, DbCompiledModel>();

    public static oraDbContext Create(string schemaName, DbConnection connection) {
        var compiledModel = modelCache.GetOrAdd(
            Tuple.Create(connection.ConnectionString, schemaName),
            t =>
            {
                var builder = new DbModelBuilder();
                builder.Configurations.Add<SomeTable1>(new SomeTable1Map(schemaName));
                builder.Configurations.Add<SomeTable2>(new SomeTable2Map(schemaName));

                var model = builder.Build(connection);
                return model.Compile();
            });

        return new oraDbContext(connection, compiledModel);
    }
}

これにはもちろん、マッピング ファイルを次のように設定する必要があります。

public class DailyDependencyTableMap : EntityTypeConfiguration<DailyDependencyTable>
{
    public SomeTableMap(string schemaName) {
        this.ToTable("SOME_TABLE_1", schemaName.ToUpper());

        //Map other properties and stuff
    }
}

複数のスキーマを使用するクエリを作成するのはやや面倒ですが、今のところ、必要なことは実行できます。

using (var connection = new OracleConnection("a connection string")) {
    using (var schema1 = oraDbContext.Create("SCHEMA1", connection))
    using (var schema2 = oraDbContext.Create("SCHEMA2", connection)) {

        var query = ((from a in schema1.SomeTable1 select new { a.Field1 }).ToList())
             .Concat((from b in schema2.SomeTable1 select new { b.Field1 }).ToList())
    }
}

 

于 2013-02-21T16:57:10.993 に答える
1

代わりに部分クラスを使用してみてください

public partial class oraDbContext : DbContext
{
    static oraDbContext() {
        Database.SetInitializer<oraDbContext>(null);
    }

    public oraDbContext(string connName)
        : base("Name=" + connName) { }

    protected override void OnModelCreating(DbModelBuilder modelBuilder) {
        schema1(modelBuilder);
        schema2(modelBuilder);
    }
}

public partial class oraDbContext : DbContext
{
    public DbSet<someTable> someTable { get; set; }
    void schema1(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new someTableMap());
    }
}
于 2013-02-16T14:55:43.687 に答える