EF数据库上下文未清除

时间:2016-12-19 02:34:08

标签: c# sql .net database entity-framework

我有一个使用Entity Framework的程序,我从一系列表中动态选择显示数据。我在数据库中的表的名称大致如下:

Revisions2016
Revisions2017
Revisions2018

到目前为止,我可以通过调用:

使用Fluent API选择不同的表
modelBuilder.Entity<Revision>().ToTable("Revisions" + suffix);

在我的数据库上下文的OnModelCreating函数内。我的问题是每当我尝试通过以下方式创建新的数据库上下文时:

public static void AccessRevisions(string tableName)
{
  using (var context = new RevisionsContext(tableName))
  {
    var revisionListing = context.Revisions.ToList();
    foreach (object o in revisionListing)
    {
      Revision r = o as Revision;
      Console.WriteLine(String.Format("ID: {0} NOTES: {1} AUTHOR: {2}", r.RevisionID, r.RevisionNotes, r.RevisionAuthor));
    }
  }
}

虽然我已经通过“using”将数据库上下文的生命周期指定为限制,但它总是似乎最终选择旧表而不是在调用函数时更改为指定的表。所以说如果我指定2016年和2017年,查询结果似乎总是2016年。

我尝试使用context.Database.Initialize(force: true);Database.SetInitializer(new DropCreateDatabaseAlways<RevisionsContext>());强制初始化上下文,但这些似乎没有做任何事情。是否有人能够指出我正确的方向如何正确地重新创建我的数据库上下文或动态切换表?

1 个答案:

答案 0 :(得分:2)

经过一段时间的搜索后,我想我找到了解决问题的潜在解决方案。我会发布我在这里发现的内容,以帮助那些一直在寻找我遇到的同样问题的解决方案的人。在Benny Michielsen的博客文章here的帮助下,我构建了我的上下文类如下:

  public class VAMPModelContext : DbContext
  {
    private VAMPModelContext(string _ConnectionString)
      : base(_ConnectionString)
    {
      Database.SetInitializer<VAMPModelContext>(null);
    }

    private VAMPModelContext(DbCompiledModel compiledModel, string connectionString)
      : base(compiledModel)
    {
      Database.SetInitializer<VAMPModelContext>(null);
      Database.Connection.ConnectionString = connectionString;
    }

    public static VAMPModelContext CreateContext(string suffix)
    {
      string connectionString = ConfigurationManager.ConnectionStrings["VAMPTest"].ConnectionString;
      VAMPModelContext dummyContext = new VAMPModelContext(connectionString);

      DbModelBuilder builder = new DbModelBuilder(DbModelBuilderVersion.Latest);
      builder.Configurations.Add(new EntityTypeConfiguration<VAMPModel>());

      // Construct model mapping for ORM
      string tableName = "VAMPModels" + suffix;
      builder.Entity<VAMPModel>().ToTable(tableName);

      // Compile ORM object, hard link connection
      DbConnection dummyConnection = dummyContext.Database.Connection;
      DbCompiledModel compiledModel = builder.Build(dummyConnection).Compile();

      // Finally make our database context
      dummyContext = new VAMPModelContext(compiledModel, connectionString);

      return dummyContext;
    }

    public virtual DbSet<VAMPModel> ModelsList { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
      // Adjust field properties for model
      modelBuilder.Entity<VAMPModel>()
          .Property(e => e.ModelCode)
          .IsUnicode(false);

      modelBuilder.Entity<VAMPModel>()
          .Property(e => e.PriceAUD)
          .HasPrecision(18, 0);

      base.OnModelCreating(modelBuilder);
    }
  }

虽然我们只能通过普通构造函数调用OnModelCreating一次,但还有另一个构造函数接受编译模型从头开始生成上下文。因此,如果我们构建自己的模型并通过它,我们可以在某种意义上“重新构建”数据库上下文。从这个课程中,我们可以简单地调用它:

using(var context = VAMPModelContext.CreateContext("2016"))
{
  var modelsListing = context.ModelsList.ToList();
  foreach (object o in modelsListing)
  {
    VAMPModel m = o as VAMPModel;
    Console.WriteLine(String.Format("MODEL ID: {0} MODEL CODE: {1} PRICE: {2}", m.ModelID, m.ModelCode, m.PriceAUD));
  }
  context.Dispose();
}

我还没有测试过所有CRUD操作的效果,但插入和查询似乎工作正常。希望这能帮助那些一直在寻找Entity-Framework动态表映射方法解决方案的人。