private void DmView_Skip() { var view = new DmView(set.Tables["ServiceTickets"]); view = view.Order((r1, r2) => string.Compare(((string)r1["Title"]), (string)r2["Title"], StringComparison.Ordinal)); Assert.Equal(17, view.Count); var view2 = view.Take(0, 2); Assert.Equal(2, view2.Count); Assert.Equal("Titre AC", (string)view2[0]["Title"]); Assert.Equal("Titre ADFVB", (string)view2[1]["Title"]); var view3 = view.Take(2, 2); Assert.Equal(2, view3.Count); Assert.Equal("Titre AEEE", (string)view3[0]["Title"]); Assert.Equal("Titre AER", (string)view3[1]["Title"]); var view4 = view.Take(4, 1); Assert.Single(view4); Assert.Equal("Titre AFBBB", (string)view4[0]["Title"]); var view5 = view.Take(5, 12); Assert.Equal(12, view5.Count); var view6 = view.Take(5, 13); Assert.Equal(12, view6.Count); var view7 = view.Take(12, 0); Assert.Empty(view7); var view8 = view.Take(17, 0); Assert.Empty(view8); Assert.Throws <Exception>(() => { var view9 = view.Take(18, 0); }); Assert.Throws <Exception>(() => { var view10 = view.Take(18, 2); }); }
/// <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(DbCommandType.BulkInsertRows); this.SetCommandParameters(DbCommandType.BulkInsertRows, bulkCommand); } else if (this.ApplyType == DmRowState.Modified) { bulkCommand = this.GetCommand(DbCommandType.BulkUpdateRows); this.SetCommandParameters(DbCommandType.BulkUpdateRows, bulkCommand); } else if (this.ApplyType == DmRowState.Deleted) { bulkCommand = this.GetCommand(DbCommandType.BulkDeleteRows); this.SetCommandParameters(DbCommandType.BulkDeleteRows, bulkCommand); } 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(failedDmtable); // Since the update and create timestamp come from remote, change name for the bulk operations var update_timestamp_column = dmChanges.Table.Columns["update_timestamp"].ColumnName; dmChanges.Table.Columns["update_timestamp"].ColumnName = "update_timestamp"; var create_timestamp_column = dmChanges.Table.Columns["create_timestamp"].ColumnName; dmChanges.Table.Columns["create_timestamp"].ColumnName = "create_timestamp"; // Make some parts of BATCH_SIZE for (int step = 0; step < dmChanges.Count; step += BATCH_SIZE) { // get upper bound max value var taken = step + BATCH_SIZE >= dmChanges.Count ? dmChanges.Count - step : BATCH_SIZE; using (var dmStepChanges = dmChanges.Take(step, taken)) { // execute the batch, through the provider ExecuteBatchCommand(bulkCommand, dmStepChanges, failedDmtable, fromScope); } } // Disposing command if (bulkCommand != null) { bulkCommand.Dispose(); bulkCommand = null; } // Since the update and create timestamp come from remote, change name for the bulk operations dmChanges.Table.Columns["update_timestamp"].ColumnName = update_timestamp_column; dmChanges.Table.Columns["create_timestamp"].ColumnName = create_timestamp_column; //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 < BATCH_SIZE && 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(); dmFailedRows = null; // return applied rows - failed rows (generating a conflict) return(dmChanges.Count - failedRows); }