理論的には、次のような名前の不明な数のテーブルを持つデータベースがあるとしましょう。
MyTable1
MyTable2
MyTable3
..
等々。これらの各テーブルには、まったく同じスキーマがあります。これらのテーブルがデータベースにいくつ存在するかはわかりません。
EF5.0 とコード ファーストを使用して、パラメーターを渡すことで、1 つの DbContext を介してこれらのテーブルのいずれかを参照できるようにしたいと考えています。
using (var db = new MyContext())
{
db.GetMyTable(2).ForEach(e => Console.WriteLine("Table 2 entry: " + e.MyField));
db.GetMyTable(5).ForEach(e => Console.WriteLine("Table 5 entry: " + e.MyField));
}
これは可能ですか?
.ToTable()
これを行う別の方法は、完全に異なるコンテキストを作成し、マッピングで正しいものを提供することです。
public class MyContext : DbContext
{
private int _tableNumber;
static MyContext()
{
Database.SetInitializer<MyContext>(null);
}
public MyContext(int tableNumber) : base("Name=TheContextName")
{
_tableNumber = tableNumber;
}
public DbSet<MyTable> MyTableEntries { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
System.Data.Entity.ModelConfiguration.Conventions.
modelBuilder.Configurations.Add(new MyTableMap(_tableNumber));
}
}
public class MyTableMap : EntityTypeConfiguration<MyTable>
{
public MyTableMap(int tableNumber)
{
// Primary Key
this.HasKey(t => t.id);
// Table & Column Mappings
this.ToTable("MyTable" + tableNumber);
this.Property(t => t.id).HasColumnName("id");
this.Property(t => t.n).HasColumnName("MyField");
}
}
そして、処理したいテーブルに基づいて、別のコンテキストで操作できます。
Console.WriteLine("Contents of MyTable1:");
using (var db = new MyContext(1))
{
db.MyTableEntries.ToList().ForEach(n => Console.WriteLine(n.MyField));
}
Console.WriteLine("Contents of MyTable2:");
using (var db = new MyContext(2))
{
db.MyTableEntries.ToList().ForEach(n => Console.WriteLine(n.MyField));
}
ただし、OnModelCreating()
コンテキスト内では最初のインスタンス化で 1 回しか呼び出されないため、そのテーブルは常に MyTable1 にマップされます。OnModelCreating()
毎回呼び出されるようにオフにできるある種のキャッシュはありますか?もしそうなら、これは良い考えですか? これを行うよりエレガントな方法はありますか?