您可以将 MS 同步框架与 sql 服务器始终加密的表一起使用吗

Can you use MS sync framework with sql server always encrypted tables

我遇到以下错误:

Operandentypkollision: nvarchar(max) ist inkompatibel mit nvarchar(max) encrypted with (encryption_type = 'RANDOMIZED', encryption_algorithm_name = 'AEAD_AES_256_CBC_HMAC_SHA_256', column_encryption_key_name = 'CEK_Auto1', column_encryption_key_database_name =

环境:

我在远程服务器上创建了一个 table“TestTable”,其中包含两列,test_id (pk, auto_increment) 和 test_data (nvarchar(max) ).我已经启用 sql 始终通过向导加密并测试加密,一切正常。

现在我已经将 MDF 从远程服务器复制到安装了 LocalDB 的本地客户端并附加了 MDF。我已将加密证书复制到本地计算机个人当前用户存储并测试访问权限,一切正常。

我已将以下连接字符串添加到我的 vb winforms .net 4.7.2 应用程序 app.config:

<connectionStrings>
    <add name="local" connectionString="Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\path\to.mdf;Column Encryption Setting=enabled;Initial Catalog=MyCatalog;Integrated Security=True"
      providerName="System.Data.SqlClient" />
    <add name="remote" connectionString="Data Source=myserver.some.where\PRODDB;Initial Catalog=MyCatalog;Column Encryption Setting=enabled;Persist Security Info=True;User ID=xxxx;Password=xxxx"
      providerName="System.Data.SqlClient" />
  </connectionStrings>

我已将两个连接都绑定到一个网格并获得了相同的结果。 从我的角度来看,两个连接字符串都是正确的,解密也能正常工作。

问题:

我想使用 Microsoft sync 框架使这两个数据库保持同步。

我使用以下代码:

Public Class dbSync
    Private operations As New ConnectionProtection(Application.ExecutablePath)
    Public Sub doSync()
        operations.DecryptFile()

        Dim localStr As String = ConfigurationManager.ConnectionStrings("localServer").ConnectionString
        Dim OnlineStr As String = ConfigurationManager.ConnectionStrings("remoteServer").ConnectionString

        sync("TestTable", localStr, OnlineStr)
   
        operations.EncryptFile()
    End Sub


    Private Sub Init(ByVal table As String, ByVal localStr As String, ByVal OnlineStr As String)
        Try





            Using servCon As SqlConnection = New SqlConnection(OnlineStr)
                    Using localCon As SqlConnection = New SqlConnection(localStr)
                        Dim scopeDesc As DbSyncScopeDescription = New DbSyncScopeDescription(table)
                        Dim tableDesc As DbSyncTableDescription = SqlSyncDescriptionBuilder.GetDescriptionForTable(table, servCon)
                        scopeDesc.Tables.Add(tableDesc)

                        Dim servProv As SqlSyncScopeProvisioning = New SqlSyncScopeProvisioning(servCon, scopeDesc)
                        servProv.SetCreateTrackingTableDefault(DbSyncCreationOption.CreateOrUseExisting)

                        servProv.Apply()
                        Dim localProv As SqlSyncScopeProvisioning = New SqlSyncScopeProvisioning(localCon, scopeDesc)
                        localProv.SetCreateTrackingTableDefault(DbSyncCreationOption.CreateOrUseExisting)
                        localProv.Apply()

                    End Using
                End Using


        Catch ex As Exception

        End Try

    End Sub

    Private Sub sync(ByVal scope As String, ByVal localStr As String, ByVal OnlineStr As String)
        Init(scope, localStr, OnlineStr)


        Using servCon As SqlConnection = New SqlConnection(OnlineStr)
            Using localCon As SqlConnection = New SqlConnection(localStr)

                Dim agent As SyncOrchestrator = New SyncOrchestrator
                agent.LocalProvider = New SqlSyncProvider(scope, localCon)
                agent.RemoteProvider = New SqlSyncProvider(scope, servCon)
                agent.Direction = SyncDirectionOrder.DownloadAndUpload

                Dim syncRelRemote As RelationalSyncProvider = TryCast(agent.RemoteProvider, RelationalSyncProvider)
                AddHandler syncRelRemote.SyncProgress, AddressOf dbProvider_SyncProgress

                Dim syncRelLocalFailed As RelationalSyncProvider = TryCast(agent.LocalProvider, RelationalSyncProvider)
                AddHandler syncRelLocalFailed.ApplyChangeFailed, AddressOf dbProvider_SyncProcessFailed

                Dim syncRelRemoteFailed As RelationalSyncProvider = TryCast(agent.LocalProvider, RelationalSyncProvider)
                AddHandler syncRelRemoteFailed.ApplyChangeFailed, AddressOf dbProvider_SyncProcessFailed

                agent.Synchronize()

            End Using
        End Using


        CleanUp(scope, localStr, OnlineStr)


    End Sub

    Private Shared Sub dbProvider_SyncProgress(ByVal sender As Object, ByVal e As DbSyncProgressEventArgs)

    End Sub

    Private Shared Sub dbProvider_SyncProcessFailed(ByVal sender As Object, ByVal e As DbApplyChangeFailedEventArgs)

    End Sub
    Public Enum DbConflictType
        ErrorsOccured = 0
        LocalUpdateRemoteUpdate = 1
        LocalUpdateRemoteDelete = 2
        LocalDeleteRemoteUpdate = 3
        LocalInsertRemoteInsert = 4
        LocalDeleteRemoteDelete = 5
    End Enum

    Private Shared Sub CleanUp(ByVal scope As String, ByVal localStr As String, ByVal OnlineStr As String)
        Using servCon As SqlConnection = New SqlConnection(OnlineStr)
            Using localCon As SqlConnection = New SqlConnection(localStr)
                Dim serverDep As SqlSyncScopeDeprovisioning = New SqlSyncScopeDeprovisioning(servCon)
                Dim localDep As SqlSyncScopeDeprovisioning = New SqlSyncScopeDeprovisioning(localCon)
                serverDep.DeprovisionScope(scope)
                serverDep.DeprovisionStore()
                localDep.DeprovisionScope(scope)
                localDep.DeprovisionStore()

            End Using
        End Using
    End Sub



End Class

错误发生在:

servProv.Apply()

正在尝试提供。

当我在不使用 always encrypted 的情况下尝试所有操作时,同步工作完美,跟踪table已创建,一切正常。

让我疑惑的是,当我看到 var tableDesc

Dim tableDesc As DbSyncTableDescription = SqlSyncDescriptionBuilder.GetDescriptionForTable(table, servCon)

是属性tableDesc.columns(1).Type是nvarchar,不管我把servCon换成localCon。所以类型似乎正确,但在应用配置时我收到错误。

我觉得我需要以某种方式调整 tableDesc,但找不到什么。

我希望我能正确描述我的问题,这是我的第一个 Whosebug-post(是的 :-))

鉴于 Sync Framework 完全不受支持并且在过去 10 年内没有更新 - 不,你不能。欢迎。