Example #1
0
        /// <summary>
        /// Launch apply bulk changes
        /// </summary>
        /// <returns></returns>
        public int ApplyBulkChanges(DmView dmChanges, ScopeInfo fromScope, List <SyncConflict> conflicts)
        {
            DbCommand bulkCommand = null;

            if (this.applyType == DmRowState.Added)
            {
                bulkCommand = this.GetCommand(DbObjectType.BulkInsertProcName);
            }
            else if (this.applyType == DmRowState.Modified)
            {
                bulkCommand = this.GetCommand(DbObjectType.BulkUpdateProcName);
            }
            else if (this.applyType == DmRowState.Deleted)
            {
                bulkCommand = this.GetCommand(DbObjectType.BulkDeleteProcName);
            }
            else
            {
                throw new Exception("DmRowState not valid during ApplyBulkChanges operation");
            }

            if (Transaction != null && Transaction.Connection != null)
            {
                bulkCommand.Transaction = Transaction;
            }

            DmTable batchDmTable  = dmChanges.Table.Clone();
            DmTable failedDmtable = new DmTable {
                Culture = CultureInfo.InvariantCulture
            };

            // Create the schema for failed rows (just add the Primary keys)
            this.AddSchemaForFailedRowsTable(batchDmTable, failedDmtable);

            int batchCount = 0;
            int rowCount   = 0;

            foreach (var dmRow in dmChanges)
            {
                // Cancel the delete state to be able to get the row, more simplier
                if (applyType == DmRowState.Deleted)
                {
                    dmRow.RejectChanges();
                }

                // Load the datarow
                DmRow dataRow = batchDmTable.LoadDataRow(dmRow.ItemArray, false);

                // Apply the delete
                // is it mandatory ?
                if (applyType == DmRowState.Deleted)
                {
                    dmRow.Delete();
                }

                batchCount++;
                rowCount++;

                if (batchCount != 500 && rowCount != dmChanges.Count)
                {
                    continue;
                }

                // Since the update and create timestamp come from remote, change name for the bulk operations
                batchDmTable.Columns["update_timestamp"].ColumnName = "update_timestamp";
                batchDmTable.Columns["create_timestamp"].ColumnName = "create_timestamp";

                // execute the batch, through the provider
                ExecuteBatchCommand(bulkCommand, batchDmTable, failedDmtable, fromScope);

                // Clear the batch
                batchDmTable.Clear();

                // Recreate a Clone
                // TODO : Evaluate if it's necessary
                batchDmTable = dmChanges.Table.Clone();
                batchCount   = 0;
            }

            // Update table progress
            //tableProgress.ChangesApplied = dmChanges.Count - failedDmtable.Rows.Count;

            if (failedDmtable.Rows.Count == 0)
            {
                return(dmChanges.Count);
            }


            // Check all conflicts raised
            var failedFilter = new Predicate <DmRow>(row =>
            {
                if (row.RowState == DmRowState.Deleted)
                {
                    return(failedDmtable.FindByKey(row.GetKeyValues(DmRowVersion.Original)) != null);
                }
                else
                {
                    return(failedDmtable.FindByKey(row.GetKeyValues()) != null);
                }
            });



            // New View
            var dmFailedRows = new DmView(dmChanges, failedFilter);

            // Generate a conflict and add it
            foreach (var dmFailedRow in dmFailedRows)
            {
                conflicts.Add(GetConflict(dmFailedRow));
            }

            int failedRows = dmFailedRows.Count;

            // Dispose the failed view
            dmFailedRows.Dispose();

            // return applied rows - failed rows (generating a conflict)
            return(dmChanges.Count - failedRows);
        }