使用Microsoft同步框架将两个表同步到一个读取表中

时间:2012-07-26 14:21:02

标签: microsoft-sync-framework

我有两个sql server表,我想将它们同步到一个读取sql数据库。我想使用同步框架将源数据库中的数据压缩到读数据库中的一个表中。我可以这样做吗?

3 个答案:

答案 0 :(得分:1)

源和目标中的模式需要匹配。您可以添加一个视图,该视图连接源数据库中的两个源表,并以与“读取”数据库期望的格式相同的格式显示数据。

答案 1 :(得分:0)

如果您使用的是较旧的提供程序(VS本地数据库缓存项目项目使用的提供程序),则可以在服务器端使用视图,但是,您的客户端只能是SQL Ce。但即使这很棘手,如果在两个源表上发生更改,会构成更改的行吗?如果表1更新而表2不更新,反之亦然?

较新的SqlSyncProvider提供程序不支持视图,因为其更改跟踪基于触发器,并且整个配置对表有效。

@Scott,架构或表格结构不需要匹配。

答案 2 :(得分:0)

我想,我正在努力做同样的事情。 这是我在stackoverflow上的问题: Merging 2 tables in a single table with different schema

我曾经解决过这个问题,并且达到了一些成果...... 现在,我正在研究仅在PERSON表中跟踪更改的情况(因此,如果ADDRESS中的某些内容发生更改,则更改不会同步)。但我想可以改进代码来跟踪ADDRESS中的更改......而且现在我没有考虑目标数据库中的更改(在CUSTOMER表中)。我认为这将更难编码......

无论如何,我的解决方案为changesSelected添加了一个处理程序,在那里我改变了DataTable,添加了我需要的列(地址和城市)。我通过SQL SELECT获取地址和城市并更新行...这适用于更新和插入的行... 删除的行会引发问题。在我的db CUSTOMER中,主键必须是Id-Address,而不仅仅是Id(或者我不能为每个PERSON提供多个ADDRESS)。因此,当SyncFX尝试执行删除时,密钥不匹配,删除不会影响任何行...我不知道如何更改状态已删除的DataRow,我也无法得到来自db的地址...所以我在删除的DataRow中没有Id-Address信息... 现在,我只能使用Id(已删除行的唯一可用信息)执行sql DELETE ...

请尝试改进代码并回复,以便我们互相帮助!

这是代码。首先是addhandler,然后将代码放入处理程序。

 AddHandler remoteProvider.ChangesSelected, AddressOf remoteProvider_ChangesSelected

...

Private Shared Sub remoteProvider_ChangesSelected(ByVal sender As Object, ByVal e As DbChangesSelectedEventArgs)

        If (e.Context.DataSet.Tables.Contains("PersonGlobal")) Then
            Dim person = e.Context.DataSet.Tables("PersonGlobal")

            Dim AddressColumn As New DataColumn("Address")
            AddressColumn.DataType = GetType(String)
            AddressColumn.MaxLength = 10
            AddressColumn.AllowDBNull = False
            'NULL is not allowed, so set a defaultvalue
            AddressColumn.DefaultValue = "Nessuna"

            Dim CityColumn As New DataColumn("City")
            CityColumn.DataType = GetType(String)
            CityColumn.AllowDBNull = False
            CityColumn.DefaultValue = 0

            persona.Columns.Add(AddressColumn)
            persona.Columns.Add(CityColumn)

            Dim newPerson = person.Clone()

            For i = 0 To person.Rows.Count - 1 Step 1

                Dim row = person.Rows(i)

                If (row.RowState <> DataRowState.Deleted) Then
                    Dim query As String = "SELECT * FROM dbo.address WHERE Id = " & row("AddressId")

                    Dim sqlCommand As New SqlCommand(query, serverConn)
                    serverConn.Open()
                    Dim reader As SqlDataReader = sqlCommand.ExecuteReader()
                    Try
                        While reader.Read()
                            row("Address") = CType(reader("Address"), String)
                            row("City") = CType(reader("City"), String)
                            ' Solo importando mantengo i valori di RowState
                            newPerson.ImportRow(row)
                        End While
                    Finally
                        reader.Close()
                    End Try
                    serverConn.Close()
                Else
                    ' TODO - Non funziona la cancellazione!!!
                    ' La cancellazione cerca la chiave primaria su cliente, che è ID-Via
                    ' Noi abbiamo l'ID corretto, ma "nessuna" come via...
                    ' Dobbiamo recuperare la via giusta...

                    Dim query As String = "DELETE FROM dbo.customer WHERE Id = " & row("Id", DataRowVersion.Original)

                    Dim sqlCommand As New SqlCommand(query, clientConn)
                    clientConn.Open()
                    sqlCommand.ExecuteNonQuery()
                    clientConn.Close()
                End If
            Next

            newPerson.Columns.Remove(newPerson.Columns("AddressId"))

            e.Context.DataSet.Tables.Remove(person)
            e.Context.DataSet.Tables.Add(newPerson)
        End If

    End Sub