0

ある範囲の登録でのみ有効なスコープがあります (たとえば、ID が 1 から 3 の範囲の登録)

したがって、リモートデータベースに次の登録があると仮定します。

ID --- 名前

1 --- 名前1

2 --- 名前2

3 --- 名前3

4 --- 名前4

5 --- 名前5

私のクライアントで、id が 1、2、または 3 (スコープに属する) であるレジストリを変更すると、同期は正常に機能します。

しかし、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 ID を PK として使用することはお勧めできません。ID パーティショニングを行わない限り、そうではありません (クライアントは 1 から 100,000、クライアント 2 は 100,001 から 200,000 など)。

于 2014-01-27T14:55:31.937 に答える