0

我有一个仅对某些范围的寄存器生效的范围(例如,ID 介于 1 和 3 之间的寄存器范围)

所以,让我们假设我在远程数据库上有以下注册:

ID --- 姓名

1 --- 名称1

2 --- 名称2

3 --- 名称3

4 --- 名称4

5 --- 名称5

在我的客户端上,如果我对 id 为 1、2 或 3(属于范围)的 regists 进行更改,则同步工作正常。

但是,如果我在 ID 为 4 的客户端数据库中添加一个新行,则此注册表将与远程数据库中具有相同 ID 的注册表重叠,并引发任何失败事件之王。

为什么会这样?由于ID已经存在于远程数据库中,所以应该插入注册表对吗?

这是我的服务器配置:

DbSyncScopeDescription scopeTemplateDesc = new DbSyncScopeDescription(TemplateForNames);
        scopeTemplateDesc.UserComment = "Template test";

        DbSyncTableDescription NamesDescription =
            SqlSyncDescriptionBuilder.GetDescriptionForTable("Names", ServerConn);


        scopeTemplateDesc.Tables.Add(NamesDescription);
        SqlSyncScopeProvisioning serverTemplate =
            new SqlSyncScopeProvisioning(ServerConn, scopeTemplateDesc, SqlSyncScopeProvisioningType.Template);


        serverTemplate.Tables["Names"].AddFilterColumn("IDName");
        serverTemplate.Tables["Names"].FilterClause = @"[side].[IDName] in
                                                                        ( 
                                                                            1,2,3
                                                                        )";
        try
        {
            serverTemplate.Apply();
        }
        catch (Exception)
        {
            Console.WriteLine("...");
        }

        // Scope
        SqlSyncScopeProvisioning serverDBProvisiong = new SqlSyncScopeProvisioning(ServerConn);
        serverDBProvisiong.PopulateFromTemplate("ScopeNamesParaUtilizador", TemplateForNames);

        serverDBProvisiong.UserComment = "Scope para o utilizador sincronizar os seus nomes";

        if (!serverDBProvisiong.ScopeExists("ScopeNamesParaUtilizador"))
        {
            try
            {
                serverDBProvisiong.Apply();
            }
            catch (Exception) { Console.WriteLine("..."); }
        }

此代码适用于本地数据库:

DbSyncScopeDescription serverScopeDescForBranch
            = SqlSyncDescriptionBuilder.GetDescriptionForScope("ScopeNamesParaUtilizador", ServerConn);

        SqlSyncScopeProvisioning branchProvision = new SqlSyncScopeProvisioning(ClientConn, serverScopeDescForBranch);
        if (!branchProvision.ScopeExists("ScopeNamesParaUtilizador"))
        {
            branchProvision.Apply();
        }

这是同步代码:

SqlSyncProvider remoteProvider = new SqlSyncProvider("ScopeNamesParaUtilizador", ServerConn);
        SqlSyncProvider localProvider = new SqlSyncProvider("ScopeNamesParaUtilizador", ClientConn);

        SyncOrchestrator syncOrchestrator = new SyncOrchestrator();
        syncOrchestrator.LocalProvider = localProvider;
        syncOrchestrator.RemoteProvider = remoteProvider;

        syncOrchestrator.Direction = SyncDirectionOrder.UploadAndDownload;

        ((SqlSyncProvider)syncOrchestrator.LocalProvider).ApplyChangeFailed +=
                new EventHandler<DbApplyChangeFailedEventArgs>(SynchronizationBusinessRules_ApplyChangeFailed);

        ((SqlSyncProvider)syncOrchestrator.RemoteProvider).ApplyChangeFailed +=
            new EventHandler<DbApplyChangeFailedEventArgs>(SynchronizationBusinessRules_ApplyChangeFailed);
        try
        {
            SyncOperationStatistics syncStats = syncOrchestrator.Synchronize();

            Console.WriteLine("Start Time: " + syncStats.SyncStartTime);
            Console.WriteLine("Total Changes Uploaded: " + syncStats.UploadChangesTotal);
            Console.WriteLine("Total Changes Downloaded: " + syncStats.DownloadChangesTotal);
            Console.WriteLine("Complete Time: " + syncStats.SyncEndTime);
        }
        catch (Exception ex)
        {

        }

static void SynchronizationBusinessRules_ApplyChangeFailed(object sender, DbApplyChangeFailedEventArgs e)
    {
        Console.WriteLine(e.Conflict.ErrorMessage);
    }
4

1 回答 1

0

您的客户端和同步不知道服务器中的现有行,因此更改已上传到服务器。对于已经存在的行,同步将失败(假设 id 是您的 PK)并且您将遇到冲突(插入 - 插入)

您必须处理它并告诉同步如何处理它,从客户端应用行或在服务器中保留行。

如果您正在进行同步,那么将身份 ID 用作 PK 并不是一个好主意。除非您进行 ID 分区(客户端获取 1-100,000,客户端 2、100,001 到 200,000 等...)

于 2014-01-27T14:55:31.937 回答