我正在开始一个使用实体框架的新项目。我研究了如何创建数据库的选项,发现代码优先迁移最有意义(如果您需要知道原因,请参阅底部)。Code-First Migrations 让我可以使用任意 SQL,这意味着我仍然可以完全控制。在实践中,我发现问题在于,对于某些常见任务,下降到 SQL 似乎非常重复。
出于我的目的,我不在乎迁移中的扩展与提供者无关(我内联的 SQL 不是)。但是,我并没有真正在迁移框架中找到一个好的接缝或扩展点来添加这些东西。
举一个具体的例子,假设我想为 MS-SQL 复制指定一个 RowGuid 列。每一次出现都采取以下形式
Sql(
string.Format(
"Alter Table {0} Alter Column {1} Add ROWGUIDCOL",
table,
column ));
所以我写静态方法来摆脱一些冗余
Sql( MigrationHelper.SetRowGuid( table, column );
-或者-
MigrationHelper.SetRowGuid(Sql, table, column); //passing the Sql method
可能可以在 DbMigration 上创建这些扩展方法中的任何一个,并通过以下方式访问它们this.
但这看起来仍然不合适:
CreateTable(
"dbo.CustomerDirectory",
c => new
{
Uid = c.Int(nullable: false),
CustomerUid = c.Int(nullable: false),
Description = c.String(nullable: false, maxLength: 50, unicode: false),
RowGuid = c.Guid(nullable: false),
})
.PrimaryKey(t => t.Uid)
.ForeignKey("dbo.Customer", t => t.CustomerUid);
this.SetRowGuid( Sql, "dbo.CustomerDirectory", "RowGuid" );
//Custom method here because of desired naming convention of Constraint
this.SetDefaultConstraint( Sql, "dbo.CustomerDirectory", "''" ):
这不是很糟糕,但对我来说仍然感觉像是一个黑客。我必须重复表名,并且需要确保生成的列名正确。我发现表名需要重复很多,但列也是如此。然而,我真正想要做的是添加到刚刚发生的表名和列名都已知的表声明中。
但是,我找不到一个好的扩展点来扩展流畅的界面或以一种感觉一致的方式扩展代码优先迁移。我错过了什么吗?有没有人找到这样做的好方法?
关于我为什么处于这种情况的一些理由:
由于某些原因,我不喜欢使用通用自定义属性解决方案来指示非映射数据库的通用解决方案,但最强烈的原因是它们不会被迁移自动拾取,这意味着额外的维护。模型优先的解决方案已经过时了,因为它们不能完全控制数据库。Database-First 之所以吸引人,是因为它具有控制性;但是,它没有 Code-First Migrations 提供的开箱即用的变更管理功能。因此,代码优先迁移似乎是赢家,因为 [代码优先] 模型驱动的更改是自动的,这意味着只需维护一件事。