您可以将 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 =
环境:
- Visual Studio 2019 企业
- SQL 服务器 2019 LocalDB (localServer)
- SQL Server 2019 标准版(远程服务器)
我在远程服务器上创建了一个 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 年内没有更新 - 不,你不能。欢迎。
我遇到以下错误:
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 =
环境:
- Visual Studio 2019 企业
- SQL 服务器 2019 LocalDB (localServer)
- SQL Server 2019 标准版(远程服务器)
我在远程服务器上创建了一个 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 年内没有更新 - 不,你不能。欢迎。