有没有办法直接使用 DbModelBuilder 使用 EF6 创建 table?
Is there a way to create a table with EF6 using a DbModelBuilder directly?
我正在寻找一种在我的数据库中直接为临时实体创建 table 的方法。由于数据库可以通过连接字符串定义,例如 postgres 和 Oracle 之间创建语句的语法可能不同 - 因此我不能将它写成纯文本命令。
有人知道从 EF6 中的 Entity / DbModelBuilder / DbModel / DbCompiledModel 实现这个的方法吗?我不得不提一下,我不能使用 EF Core。
这是我目前的设置:
public class TMPEntity
{
public TMPEntity();
public string EntityId{ get; set; }
}
var modelBuilder = new DbModelBuilder();
// set default schema
modelBuilder.HasDefaultSchema("SCHEMA");
// Create Table in this schema
modelBuilder.Entity<TMPEntity>().ToTable(tableName: "TMPEntityTable", schemaName: "SCHEMA");
modelBuilder.Entity<TMPEntity>().HasKey(
h => new
{
h.EntityId
});
var ctx = modelBuilder
.Build(context.Database.Connection)
.Compile();
提前致谢!
这是我最后得到的。我想这不是最好的解决方案,但至少是一个可行的解决方案,直到得到进一步的建议:-)
因为我没有设法从 EdmModel class 或 DBModel 生成有效的 SQL,所以我创建了一个 DbMigration class,它现在创建了 table。不如 ModelBuilder 方法聪明,但正如我提到的 - 工作:
internal class CreateSingleTableMigration: DbMigration
{
public override void Up()
{
CreateTable(
"\"SCHEMA\".\"TMPEntityTable\"",
c => new
{
// Single column
EntityId= c.String(nullable: false, maxLength: 150)
// Further columns go in here ...
})
.PrimaryKey(t => new { t.EntityId /*Combined PK goes here*/ });
}
}
现在的问题是,如何使用选定的 IDbProvider 从中生成并执行有效的 SQL。由于我想重用现有的 DbContext,所有必需的信息都可以在 class.
中找到
// If database exists
if (context.Database.Exists())
{
// Get the corresponding DbProviderServices the Provider of the current Connection has to offer
var serv = DbProviderServices.GetProviderServices(context.Database.Connection);
// Get the provider manifest token
var tkn = serv.GetProviderManifestToken(context.Database.Connection);
// Get the PropertyInfo of the internal "Operations" property
var prop = typeof(InitializeHistorizationMigration)
.GetProperty("Operations", BindingFlags.NonPublic | BindingFlags.Instance);
// If Property "operations" was found
if (prop != null)
{
// get SQL Generator for the current provider
var generator = new Configuration().GetSqlGenerator(FWLPDataContext.Provider);
// Create instance of the CreateTable-Migration
var tmpMig= new CreateSingleTableMigration();
// Apply it, so property "Operation" is filled
tmpMig.Up();
// Get the operations as a List of single MigrationOperation
var operations = (prop.GetValue(tmpMig) as IEnumerable<MigrationOperation>).ToList();
// Generate SQL and run it against the database using the DbContext Connection
foreach (var item in generator.Generate(operations, tkn))
{
context.Database.ExecuteSqlCommand(item.Sql);
}
}
}
使用 postgres 执行 SQL 脚本生成错误:SqlState: 3F000
MessageText:未选择要在
中创建的架构
这就是我在 CreateSingleTableMigration class 中添加架构的原因,在连接字符串中设置搜索路径没有帮助。
如果您有更好的优化方法或想法,请告诉我!
我正在寻找一种在我的数据库中直接为临时实体创建 table 的方法。由于数据库可以通过连接字符串定义,例如 postgres 和 Oracle 之间创建语句的语法可能不同 - 因此我不能将它写成纯文本命令。
有人知道从 EF6 中的 Entity / DbModelBuilder / DbModel / DbCompiledModel 实现这个的方法吗?我不得不提一下,我不能使用 EF Core。
这是我目前的设置:
public class TMPEntity
{
public TMPEntity();
public string EntityId{ get; set; }
}
var modelBuilder = new DbModelBuilder();
// set default schema
modelBuilder.HasDefaultSchema("SCHEMA");
// Create Table in this schema
modelBuilder.Entity<TMPEntity>().ToTable(tableName: "TMPEntityTable", schemaName: "SCHEMA");
modelBuilder.Entity<TMPEntity>().HasKey(
h => new
{
h.EntityId
});
var ctx = modelBuilder
.Build(context.Database.Connection)
.Compile();
提前致谢!
这是我最后得到的。我想这不是最好的解决方案,但至少是一个可行的解决方案,直到得到进一步的建议:-)
因为我没有设法从 EdmModel class 或 DBModel 生成有效的 SQL,所以我创建了一个 DbMigration class,它现在创建了 table。不如 ModelBuilder 方法聪明,但正如我提到的 - 工作:
internal class CreateSingleTableMigration: DbMigration
{
public override void Up()
{
CreateTable(
"\"SCHEMA\".\"TMPEntityTable\"",
c => new
{
// Single column
EntityId= c.String(nullable: false, maxLength: 150)
// Further columns go in here ...
})
.PrimaryKey(t => new { t.EntityId /*Combined PK goes here*/ });
}
}
现在的问题是,如何使用选定的 IDbProvider 从中生成并执行有效的 SQL。由于我想重用现有的 DbContext,所有必需的信息都可以在 class.
中找到// If database exists
if (context.Database.Exists())
{
// Get the corresponding DbProviderServices the Provider of the current Connection has to offer
var serv = DbProviderServices.GetProviderServices(context.Database.Connection);
// Get the provider manifest token
var tkn = serv.GetProviderManifestToken(context.Database.Connection);
// Get the PropertyInfo of the internal "Operations" property
var prop = typeof(InitializeHistorizationMigration)
.GetProperty("Operations", BindingFlags.NonPublic | BindingFlags.Instance);
// If Property "operations" was found
if (prop != null)
{
// get SQL Generator for the current provider
var generator = new Configuration().GetSqlGenerator(FWLPDataContext.Provider);
// Create instance of the CreateTable-Migration
var tmpMig= new CreateSingleTableMigration();
// Apply it, so property "Operation" is filled
tmpMig.Up();
// Get the operations as a List of single MigrationOperation
var operations = (prop.GetValue(tmpMig) as IEnumerable<MigrationOperation>).ToList();
// Generate SQL and run it against the database using the DbContext Connection
foreach (var item in generator.Generate(operations, tkn))
{
context.Database.ExecuteSqlCommand(item.Sql);
}
}
}
使用 postgres 执行 SQL 脚本生成错误:SqlState: 3F000 MessageText:未选择要在
中创建的架构这就是我在 CreateSingleTableMigration class 中添加架构的原因,在连接字符串中设置搜索路径没有帮助。
如果您有更好的优化方法或想法,请告诉我!