asp.net - 如何使用 Entity Framework 代码优先实现在迁移时更新每一行的唯一值

标签 asp.net vb.net entity-framework ms-access jet-ef-provider

我正在寻找一种适当的方法来扩展现有数据库,基于 Entity Framework 6 代码优先实现,并向表中每个现有行的新字段添加唯一值。

到目前为止,我已经创建了一个添加新字段的迁移。

Up 方法如下所示:

Public Overrides Sub Up()
    AddColumn("dbo.Customers", "UniqueCode", Function(c) c.String(unicode:=False))
End Sub

我陷入了新字段应该填充唯一(计算出的)值的困境。为了简单起见,假设数据库中的每个现有行都应在迁移时分配一个 GUID。

使用这样的 SQL 语句将更新具有相同 GUID 的所有行。但我需要它对于每一行都是唯一的。

Sql("Update dbo.Customers SET UniqueCode = '" & Guid.NewGuid().ToString)

在 Up 方法中使用 foreach 似乎有点错误......这种情况下的最佳实践是什么?

另外:我使用的数据库是access,所以不能使用newid()或者random()。 GUID 旨在作为以编程方式计算的值的虚拟值。它将是客户的一些其他属性的哈希值。所以必须通过迁移来计算和更新。

最佳答案

我发现以下方法最适合我的情况。我建议将数据库和数据更改拆分为 2 次迁移,这样您就可以使用该框架来进行所有更改,并且完全向上和向下兼容。

这是我的方法的详细信息:

按照 Bradley Uffner 的建议,我循环遍历数据并逐行更新它。但是,在同一个迁移中执行此操作会引发错误:

The model backing the 'DbContext' context has changed since the database was created. Consider using Code First Migrations to update the database.

在迁移过程中使用 DbContext 会导致不一致的状态。模型已处于迁移后状态,但数据库的表中仍具有迁移前状态。模型和数据库不匹配,导致上述错误。为了实现这项工作,我必须禁用模型检查。

引用:Change data in migration Up method - Entity Framework

在上面的线程中,我发现了将数据库更改与数据更改分开的建议。我就是这么做的。

我创建了一个迁移来更新数据库

    Public Overrides Sub Up()
        AddColumn("dbo.Customers", "WebCode", Function(c) c.String(unicode := false))
    End Sub

    Public Overrides Sub Down()
        DropColumn("dbo.Customers", "WebCode")
    End Sub

运行更新数据库命令。然后创建第二个迁移来进行数据更改。 UpDown 方法在创建时将为空。这是我用来逐行更新数据的代码。

    Public Overrides Sub Up()
        Dim DbContext As New Data.DbContext

        For Each customer In DbContext.Customers.Where(Function(x) String.IsNullOrEmpty(x.WebCode))
            customer.WebCode = GetWebCode(customer)
        Next

        DbContext.SaveChanges()
    End Sub

    Public Overrides Sub Down()
        Dim DbContext As New Data.DbContext

        For Each customer In DbContext.Customers
            customer.WebCode = Nothing
        Next

        MyDbContext.SaveChanges()
    End Sub

有些人可能会争论在 Down 方法中使用简单的 SQL,例如

SQL("Update dbo.Customers SET WebCode = NULL")

效率更高。我已经尝试过,但在 JetEntityFrameworkProvider.JetMigrationSqlGenerator.GenerateSqlStatmentConcrete 遇到错误,我无法找到并修复该错误。它导致 Visual Studio 崩溃。

关于asp.net - 如何使用 Entity Framework 代码优先实现在迁移时更新每一行的唯一值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45615238/

相关文章:

c# - EF6 : getting data from derived DbSet

不使用 Global.asax 启动 ASP.NET 应用程序

asp.net - MailChimp API 3.0 订阅

asp.net-mvc - 将 MVC 应用程序发布到 azure

.net - 系统.Data.SQLite.SQLiteException : Database is locked?

c# - 为什么在 VB.NET 和 C# 中根据值检查 null 会有所不同?

visual-studio-2010 - Entity Framework 加入 ms-access

c# - Google Adword 和 asp.net 母版页

c# - 求csv文件中每一列的最大长度

vb.net - Visual Basic 问题 - Me.Hide() 或 Me.Close()