使用实体框架Code-First创建表,运行时

Ima*_*ehi 6 c# entity-framework ef-code-first ef-migrations entity-framework-6

是否可以通过使用EF Code-first 在运行时创建表?我可以使用C#CodeDOM(反射)在运行时创建我的模型类,但我无法在运行时设置我的Dbcontext类的dbSet属性.你的想法是什么?什么是在运行时动态创建表的最佳解决方案?...有些人对我说,唯一的方法是使用经典的ADO.Net.

Sam*_*ath 6

是的,你可以这样做。

您可以使用 Find the Classes 来做到这一点:

[AttributeUsage(AttributeTargets.Class)]
public class PersistentAttribute : Attribute
{
}
Run Code Online (Sandbox Code Playgroud)

现在,您可以向扫描程序集的OnModelCreating方法添加一些逻辑,context并添加具有[Persist]如下所示属性的任何类。

public class MyContext : DbContext
{
  protected override void OnModelCreating(DbModelBuilder modelBuilder)
  {
    var entityMethod = typeof(DbModelBuilder).GetMethod("Entity");

    foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
    {
      var entityTypes = assembly
        .GetTypes()
        .Where(t =>
          t.GetCustomAttributes(typeof(PersistentAttribute), inherit: true)
          .Any());

      foreach (var type in entityTypes)
      {
        entityMethod.MakeGenericMethod(type)
          .Invoke(modelBuilder, new object[] { });
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

您可以使用下面提到的基于代码的数据迁移方法,因此在将新类或属性添加到模型时会自动更改数据库。

var config = new DbMigrationsConfiguration<MyContext> { AutomaticMigrationsEnabled = true };
var migrator = new DbMigrator(config);
migrator.Update();
Run Code Online (Sandbox Code Playgroud)

您可以阅读有关此内容的更多信息:使用代码优先动态构建模型

更新:如何查询动态表?

public IEnumerable<ResultTableTemplate> GetResultsFromTable(string tableName) {
    using (var context = new MyContext()) {
        var query = context.ExecuteStoreQuery<ResultTableTemplate>("SELECT " +
            "ALL_THOSE_COLUMN_NAMES... " +
            "FROM " + tableName;

        return query.ToList();
    }
}
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅:使用实体框架从动态创建的表中查询数据