1

我正在寻找一种解决方案来重命名表的列,使用 Jet Engine 数据库提供程序(MS Access 数据库)使用实体框架代码首先迁移保留值。

由于处理 Jet Engine 和 MS Access DB,我尝试了几种方法,但它们都没有奏效。

以下是我已经尝试过的模型更改和方法的详细信息:

模型变化

(我缩短了更改以保持清晰):

    ' OLD properties
    ' Public Property WebServiceState As ServiceStateType?
    ' Public Property WebServiceRegistrationDate As DateTime?
    ' Public Property WebServiceEndOfTrialDate As DateTime?
    ' Public Property WebServiceExpirationDate As DateTime?

    ' NEW
    Public Property WebServiceState As ServiceState

除了“WebService”之外,还有其他服务类型都具有相同的属性(注册日期,...)。因此,我创建了一个ServiceState代表这些属性的新类。

Public Class ServiceState
    Public Property State As ServiceStateType?
    Public Property RegistrationDate As DateTime?
    Public Property EndOfTrialDate As DateTime?
    Public Property ServiceStopAtDate As DateTime?
End Class

移民

在迁移时,我必须将数据移动到新结构。我使用 PM-Console 和“add-migration”创建了一个迁移。这是 up 函数的自动生成代码:

    Public Overrides Sub Up()
        AddColumn("dbo.Services", "WebServiceState_State", Function(c) c.Int())
        AddColumn("dbo.Services", "WebServiceState_RegistrationDate", Function(c) c.DateTime())
        AddColumn("dbo.Services", "WebServiceState_EndOfTrialDate", Function(c) c.DateTime())
        AddColumn("dbo.Services", "WebServiceState_ServiceStopAtDate", Function(c) c.DateTime())

        DropColumn("dbo.Services", "WebServiceState")
        DropColumn("dbo.Services", "WebServiceRegistrationDate")
        DropColumn("dbo.Services", "WebServiceEndOfTrialDate")
        DropColumn("dbo.Services", "WebServiceExpirationDate")
    End Sub

使用此代码,数据将丢失,因为新旧属性之间没有数据传输。

尝试的方法

为了保留数据,我尝试了以下方法,如如何在 Entity Framework 5 Code First 迁移中重命名数据库列而不丢失数据?.

1.使用重命名列

RenameColumn("dbo.Services", "WebServiceState", "WebServiceState_State")

这不起作用。PM-Konsole 报告

无法使用 Jet 重命名对象

2.使用SQL进行更新

Sql("Update dbo.Services SET [WebServiceState_State] = [WebServiceState]")

也不行。它会引发错误GenerteSqlStatementConcrete

例外

3.使用数据库上下文在迁移Up方法中更改数据

恕我直言,这不是一种选择。这会导致状态不一致,因为模型已经处于迁移后状态,但数据库在表中仍然具有迁移前状态。模型和数据库不匹配,导致错误。

自数据库创建以来,支持“DbContext”上下文的模型已更改。考虑使用 Code First 迁移来更新数据库。

为了完成这项工作,我必须禁用模型检查,我认为这不是一件好事。(参考:迁移Up方法中的更改数据-实体框架

问题

如何根据上面提到的我正在处理的限制(主要是 Jet Engine,由于 MS Access 数据库)重命名列/保留迁移数据?

4

2 回答 2

1

ms访问的主要问题是没有SQL语句来重命名对象。唯一的方法是使用外部 DLL(通常是 ADOX)。

所以,如果你觉得可以,你可以使用 IvanStoev 的建议。唯一的问题是您的列名与属性名称不匹配(但只是一个内部问题)。

另一种可能性是添加新列,将数据从旧列复制到新列并删除旧列。

另一种可能性是您使用 ADOX。你可以使用这个源代码

https://github.com/bubibubi/EntityFrameworkCore.Jet/blob/master/src/System.Data.Jet/AdoxWrapper.cs

如果未安装 ADOX,则应用程序可以工作(但重命名会引发错误)。我正在使用它在 EF 核心提供程序中实现对象重命名以供 Microsoft 访问。

调用的方法是重命名列。

在 EF 核心的提供者(仍处于测试阶段)中实现了它。

于 2017-09-08T04:34:07.987 回答
1

除了我对 bubi 的回答的评论,这里是我最后使用的代码。确保您使用的是 JetEntityFrameworkProvider 1.2.7 或更高版本。迁移不支持以下 SQL 语句(参考)。

Public Overrides Sub Up()
    AddColumn("dbo.Services", "WebServiceState_State", Function(c) c.Int())
    AddColumn("dbo.Services", "WebServiceState_RegistrationDate", Function(c) c.DateTime())
    AddColumn("dbo.Services", "WebServiceState_EndOfTrialDate", Function(c) c.DateTime())
    AddColumn("dbo.Services", "WebServiceState_ServiceStopAtDate", Function(c) c.DateTime())

    Sql("UPDATE Services SET [WebServiceState_State] = [WebServiceState]")
    Sql("UPDATE Services SET [WebServiceState_RegistrationDate] = [WebServiceRegistrationDate]")
    Sql("UPDATE Services SET [WebServiceState_EndOfTrialDate] = [WebServiceEndOfTrialDate]")
    Sql("UPDATE Services SET [WebServiceState_ServiceStopAtDate] = [WebServiceExpirationDate]")

    DropColumn("dbo.Services", "WebServiceState")
    DropColumn("dbo.Services", "WebServiceRegistrationDate")
    DropColumn("dbo.Services", "WebServiceEndOfTrialDate")
    DropColumn("dbo.Services", "WebServiceExpirationDate")
End Sub
于 2017-09-08T12:05:03.707 回答