【问题标题】:EF6 Code First drop tables (not entire database) when model changes模型更改时,EF6 Code First 删除表(不是整个数据库)
【发布时间】:2014-06-13 15:41:27
【问题描述】:

我正在使用 Entity Framework 6 进行 Code First 开发,使用数据库迁移,并且我正在使用一个填充了示例种子数据的新数据库。我希望能够在任何时候更改模型时使用该种子数据初始化我的数据库。

问题是:我没有数据库创建权限;因此,我不能只使用DropCreateDatabaseIfModelChanges

有没有一种方法可以以编程方式删除我的所有表,还是每次都手动从数据库中删除它们?

【问题讨论】:

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


【解决方案1】:

最终,我不需要删除表,只需要删除它们包含的数据。

我最终通过简单地在我的 Seed 方法开头截断表列表来解决这个问题,基于this answer

protected override void Seed(MyContext context)
{
    var listOfTables = new List<string> { "Table1", "Table2", "Table3" };

    foreach (var tableName in listOfTables)
    {
        context.Database.ExecuteSqlCommand("TRUNCATE TABLE [" + tableName + "]");
    }

    context.SaveChanges();

    // seed data below
}

【讨论】:

  • 你不会遇到 FK 约束的问题吗?
  • 在我的情况下,我不必截断所有表,我截断的那些表没有任何 FK 约束。如果我确实需要担心这一点,我会确保以正确的顺序设置我的列表。
【解决方案2】:

如果您不使用自动迁移,而是使用基于代码的迁移,则可以使用以下命令一直返回到第一个版本:

Update-Database –TargetMigration: 0

这将在您的所有迁移中遵循向下路径,直到您拥有一个干净的数据库。然后就可以执行了:

Update-Database

这将使所有内容恢复到最新状态。此解决方案假定您已正确维护下行路径并使用迁移为您的数据播种。我为我的集成测试执行此操作,以确保我从处于预期状态的数据开始。

【讨论】:

  • 我希望这对我有用,但我后来的迁移之一为复合主键引入了一个额外的标识属性(用于 1..n 支持)。理想情况下,我会擦除迁移并添加新的初始迁移,但我不确定架构是否处于最终状态。
【解决方案3】:

我的建议是使用本地数据库或您拥有完全权限的其他数据库(Azure 很好,如果您有 MSDN 帐户则免费)。然后在确定并准备好投入生产后迁移最终的数据库模式。

话虽如此,this might be helpful,但我以前从未尝试过。

【讨论】:

    【解决方案4】:

    如果您没有访问数据库的权限,最好解决该问题。 无论如何:

      public bool TruncateTable(string connectionString, string schema, string tableName) {
            var statement = "TRUNCATE TABLE [{0}].[{1}] ;";
            statement = string.Format(statement, schema, tableName);
            return ExecuteSqlStatement(connectionString, statement);
        }
    
        public bool DeleteAllEntriesTable(string connectionString, string schema, string tableName) {
            var statement = "DELETE FROM [{0}].[{1}] ;";
            statement = string.Format(statement, schema, tableName);
            return ExecuteSqlStatement(connectionString, statement);
        }
    
        public bool ExecuteSqlStatement(string connectionString, string statement, bool suppressErrors = false) {
            int rowsAffected;
            using (var sqlConnection = new SqlConnection(connectionString)) {
                using (var sqlCommand = new SqlCommand(statement, sqlConnection)) {
                    try {
                        sqlConnection.Open();
                        rowsAffected = sqlCommand.ExecuteNonQuery(); // potential use
                    }
                    catch (Exception ex) {
                        if (!suppressErrors) {
                         // YOUR ERROR HANDLER HERE
                        }
    
                        return false;
                    }
                }
            }
    
            return true;
    

    【讨论】:

      猜你喜欢
      • 2014-06-09
      • 2017-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多