C# 实体框架代码首先返回映射到同一类的不同表的相同数据
我有一个类C# 实体框架代码首先返回映射到同一类的不同表的相同数据,c#,C#,我有一个类Timer,我想与具有相同结构的不同表一起使用,因此我要传入表名 public class TimerContext : DbContext { public DbSet<Timer> Timers { get; set; } private readonly string _tableName; public TimerContext(string tableName) : base("name=fooDb") { _t
Timer
,我想与具有相同结构的不同表一起使用,因此我要传入表名
public class TimerContext : DbContext
{
public DbSet<Timer> Timers { get; set; }
private readonly string _tableName;
public TimerContext(string tableName) : base("name=fooDb")
{
_tableName = tableName;
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Timer>().ToTable(_tableName);
base.OnModelCreating(modelBuilder);
}
}
EF将在需要时调用OnModelCreating方法来创建模型的内存中副本。完成此操作后,将使用此副本。在您的例子中,生成prevTimers的代码使用映射到当前timers表的内存中模型。如果在OnModelCreating方法上放置一个断点,您应该看到它只被调用一次 综上所述,可以深入挖掘和询问内存中的模型(必须使用老式的上下文类型,ObjectContext vs.DbContext)。使用Rowan Miller的一些代码,您可以找到映射到每个实体集的表。使用此代码,tables变量中的每个项都有一个包含数据库表名的读/写表属性。我还没有试着设置这个,但它看起来确实是合理的。当然,您需要在OnModelCreating方法之外的其他地方修改模型,比如在构造函数中,这样每次创建上下文实例时代码都会触发 *更新* 因为我总是对学习新事物感兴趣,所以我不能把它放在一边,然后编写一个测试应用程序。不幸的是,您似乎无法设置该属性(尽管它是读/写属性),因为它会抛出一个InvalidOperationException,声明该项是只读的。也许还有别的办法,但我还没有找到 *更新* 这个解决方案实际上比我第一次提到的要简单得多。DbContext类的两个构造函数接受DbCompiledModel类的实例作为其参数之一。使用DbModelBuilder类,您可以构建通常放在OnModelCreating方法中的相同代码。您可以调用该类的Build方法来创建DbModel类的实例。您可以调用此类的Compile方法来创建DbCompiledModel类的实例。唯一真正的诀窍是构建方法需要一些额外的信息(我使用了DbProviderInfo类的一个实例,但我认为您也可以使用实际的连接,但这可能会对数据库造成影响)。我已经测试了这个,这个确实可以按预期工作 类似于
DbModelBuilder builder = null;
builder = new DbModelBuilder();
builder.Entity<TestEntity>().ToTable(tableName);
DbModel model1 = null;
model1 = builder.Build(new DbProviderInfo("System.Data.SqlClient", "2012"));
builder.Entity<TestEntity>().ToTable(anotherTableName);
DbModel model2 = null;
model2 = builder.Build(new DbProviderInfo("System.Data.SqlClient", "2012"));
DbCompiledModel compiledModel1 = null;
DbCompiledModel compiledModel2 = null;
compiledMdoel1 = model1.Compile();
compiledMdoel2 = model2.Compile();
TestContext context1 = null;
TestContext context2 = null;
context1 = new TestContext(compiledModel1);
context2 = new TestContext(compiledModel2);
dbmodelbuilderbuilder=null;
builder=newdbmodelbuilder();
builder.Entity().ToTable(tableName);
DbModel model1=null;
model1=builder.Build(新的DbProviderInfo(“System.Data.SqlClient”,“2012”);
builder.Entity().ToTable(另一个表名);
DbModel model2=null;
model2=builder.Build(新的DbProviderInfo(“System.Data.SqlClient”,“2012”);
DbCompiledModel compiledModel1=null;
DbCompiledModel compiledModel2=null;
compiledDoel1=model1.Compile();
compiledDoel2=model2.Compile();
TestContext context1=null;
TestContext context2=null;
context1=新的TestContext(compiledModel1);
context2=新的TestContext(compiledModel2);
当然,TestContext类的构造函数必须将编译后的模型实例传递给基构造函数。EF将在需要时调用OnModelCreating方法来创建模型的内存副本。完成此操作后,将使用此副本。在您的例子中,生成prevTimers的代码使用映射到当前timers表的内存中模型。如果在OnModelCreating方法上放置一个断点,您应该看到它只被调用一次 综上所述,可以深入挖掘和询问内存中的模型(必须使用老式的上下文类型,ObjectContext vs.DbContext)。使用Rowan Miller的一些代码,您可以找到映射到每个实体集的表。使用此代码,tables变量中的每个项都有一个包含数据库表名的读/写表属性。我还没有试着设置这个,但它看起来确实是合理的。当然,您需要在OnModelCreating方法之外的其他地方修改模型,比如在构造函数中,这样每次创建上下文实例时代码都会触发 *更新* 因为我总是对学习新事物感兴趣,所以我不能把它放在一边,然后编写一个测试应用程序。不幸的是,您似乎无法设置该属性(尽管它是读/写属性),因为它会抛出一个InvalidOperationException,声明该项是只读的。也许还有别的办法,但我还没有找到 *更新* 这个解决方案实际上比我第一次提到的要简单得多。DbContext类的两个构造函数接受DbCompiledModel类的实例作为其参数之一。使用DbModelBuilder类,您可以构建通常放在OnModelCreating方法中的相同代码。您可以调用该类的Build方法来创建DbModel类的实例。您可以调用此类的Compile方法来创建DbCompiledModel类的实例。唯一真正的诀窍是构建方法需要一些额外的信息(我使用了DbProviderInfo类的一个实例,但我认为您也可以使用实际的连接,但这可能会对数据库造成影响)。我已经测试了这个,这个确实可以按预期工作 类似于
DbModelBuilder builder = null;
builder = new DbModelBuilder();
builder.Entity<TestEntity>().ToTable(tableName);
DbModel model1 = null;
model1 = builder.Build(new DbProviderInfo("System.Data.SqlClient", "2012"));
builder.Entity<TestEntity>().ToTable(anotherTableName);
DbModel model2 = null;
model2 = builder.Build(new DbProviderInfo("System.Data.SqlClient", "2012"));
DbCompiledModel compiledModel1 = null;
DbCompiledModel compiledModel2 = null;
compiledMdoel1 = model1.Compile();
compiledMdoel2 = model2.Compile();
TestContext context1 = null;
TestContext context2 = null;
context1 = new TestContext(compiledModel1);
context2 = new TestContext(compiledModel2);
dbmodelbuilderbuilder=null;
builder=newdbmodelbuilder();
builder.Entity().ToTable(tableName);
DbModel model1=null;
model1=builder.Build(新的DbProviderInfo(“System.Data.SqlClient”,“2012”);
builder.Entity().ToTable(另一个表名);
DbModel model2=null;
model2=builder.Build(新的DbProviderInfo(“System.Data.SqlClient”,“2012”);
DbCompiledModel已编译
DbModelBuilder builder = new DbModelBuilder();
this.OnModelCreating(builder);
var model = builder.Build(this.Database.Connection);