OnModelCreating仅在新上下文中调用一次

时间:2018-03-08 14:14:17

标签: c# entity-framework entity-framework-6

我有多个SQL服务器表相同,但内容不同。在编写代码时,我首先尝试为每个代码重用相同的db上下文,并将表名传递给上下文构造函数。

但是,每次调用构造函数时,OnModelCreating方法只会被调用一次,尽管每次都是从new创建db上下文。我该如何重置?

我尝试过使用AsNoTracking,并且我按照禁用模型缓存的方式阅读但是无法找到如何执行此操作或者这是否是最佳方法。 MSDN甚至说,通过在给定的ModelBuidler [原文如此]上设置ModelCaching属性,可以禁用此缓存,'但它不存在。

这是我的数据库背景:

public partial class MissingContext : DbContext
{
    private string tableName = "";
    public MissingContext(string tableName) : base("name=MissingContext")
    {
        this.tableName = tableName;
    }

    public virtual DbSet<MissingData> MissingDataSet { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<MissingData>()
           .ToTable(this.tableName);
    }
}

这是我使用它的代码:

List<MissingData> missingData=null;
string[] inputTables="TABLEA;TABLEB;TABLEC".Split(';');
foreach (string table in inputTables)
{
    logger.Info($"Processing {table}");
    missingData = null;

    MissingContext db = new MissingContext(table);
    var query = from d in db.MissingDataSet.AsNoTracking()
                select d;
    missingData = query.ToList();
}

在运行时,table始终具有正确的TABLEA,TABLEB,TABLEC并将其传递给db上下文构造函数,但OnModelCreating仅针对第一个循环项调用一次,因此查询对象生成的SQL始终选择来自TABLEA:

SELECT 
[Extent1].[id] AS [id], 
[Extent1].[OrganisationName] AS [OrganisationName] 
FROM [dbo].[**TABLEA**] AS [Extent1]

*道歉,如果任何代码看起来有误,我会重命名一些变量,因为它们对业务敏感。

2 个答案:

答案 0 :(得分:1)

OnModelCreating只会在默认行为中被调用一次。

根据OnModelCreating文档。

通常,只有在创建派生上下文的第一个实例时才调用此方法一次。然后缓存该上下文的模型,该模型适用于app域中上下文的所有其他实例。可以通过在给定的ModelBuidler上设置ModelCaching属性来禁用此缓存,但请注意,这会严重降低性能。通过直接使用DbModelBuilder和DbContextFactory类,可以更好地控制缓存。

答案 1 :(得分:0)

我认为这里的问题是每个表不是如何设计创建上下文的。
实体框架的设计是(在最一般的情况下),每个表将有一个表示该表中任何行的类。对于不同的表,预计将定义另一个类。然后,您获得了派生的DbContext
一个DbContext可以通过为每个表类创建适当的DbSet来为任意多个表提供服务。如果你希望他们出于某种原因在不同的环境中工作,那么EF的设计会期望从DbContext得到一个不同的类,它有自己的DbSet s。
警告:如果您只使用相同的连接到不同的数据库,意味着列完全对应等,则可以使用相同的{{ 1}},根据需要为构造函数提供不同的连接字符串。