public void Foreign() { DmRelation Relation = new DmRelation("FK_ClientType", clientTypeTable.Columns["TypeId"], clientTable.Columns["ClientType"]); _set.Relations.Add(Relation); DmRow Row = clientTable.NewRow(); Row[0] = 1; Row[1] = 1; Row[2] = "Sébastien"; clientTable.Rows.Add(Row); Row = clientTable.NewRow(); Row[0] = 2; Row[1] = 1; Row[2] = "Pierre"; clientTable.Rows.Add(Row); Row = clientTable.NewRow(); Row[0] = 3; Row[1] = 2; Row[2] = "Paul"; Row = clientTypeTable.NewRow(); Row[0] = 1; Row[1] = "Grand Compte"; clientTypeTable.Rows.Add(Row); Row = clientTypeTable.NewRow(); Row[0] = 2; Row[1] = "PME"; clientTypeTable.Rows.Add(Row); // Get all rows wher ClientType = "Grand Compte" var rowTypeGrandCompte = clientTypeTable.FindByKey(1); // Get all childs var rowsClients = rowTypeGrandCompte.GetChildRows("FK_ClientType"); Assert.Equal(2, rowsClients.Length); // Get all parents var rowClient = clientTable.Rows[0]; var rowClientType = rowClient.GetParentRow("FK_ClientType"); Assert.Equal("Grand Compte", rowClientType[1]); }
/// <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); }
public void DmTable_FindByKey() { var key = Guid.NewGuid(); var st = tbl.NewRow(); st["ServiceTicketID"] = key; st["Title"] = "Titre AER"; st["Description"] = "Description 2"; st["EscalationLevel"] = 1; st["StatusValue"] = 2; st["Opened"] = DateTime.Now; st["Closed"] = null; st["CustomerID"] = 1; tbl.Rows.Add(st); var dmRow = tbl.FindByKey(key); Assert.NotNull(dmRow); Assert.Equal(key, dmRow["ServiceTicketID"]); // Multiple Key // Check if the culture / case sensitive works as well with // string in the pkey var tbl2 = new DmTable("ServiceTickets"); tbl2.CaseSensitive = true; var id1 = new DmColumn <Guid>("ServiceTicketID"); var id2 = new DmColumn <int>("CustomerID"); var id3 = new DmColumn <string>("Title"); tbl2.Columns.Add(id1); tbl2.Columns.Add(id2); tbl2.Columns.Add(id3); var pkey = new DmKey(new DmColumn[] { id1, id2, id3 }); tbl2.PrimaryKey = pkey; tbl2.Columns.Add(new DmColumn <string>("Description")); tbl2.Columns.Add(new DmColumn <int>("StatusValue")); tbl2.Columns.Add(new DmColumn <int>("EscalationLevel")); tbl2.Columns.Add(new DmColumn <DateTime>("Opened")); tbl2.Columns.Add(new DmColumn <DateTime>("Closed")); var rowPkeyGuid = Guid.NewGuid(); var row = tbl2.NewRow(); row["ServiceTicketID"] = rowPkeyGuid; row["CustomerID"] = 1; row["Title"] = "Titre AER"; row["Description"] = "Description 2"; row["EscalationLevel"] = 1; row["StatusValue"] = 2; row["Opened"] = DateTime.Now; row["Closed"] = null; tbl2.Rows.Add(row); row = tbl2.NewRow(); row["ServiceTicketID"] = rowPkeyGuid; row["CustomerID"] = 1; row["Title"] = "Titre DE"; row["Description"] = "Description 2"; row["EscalationLevel"] = 3; row["StatusValue"] = 2; row["Opened"] = DateTime.Now; row["Closed"] = null; tbl2.Rows.Add(row); var dmRow2 = tbl2.FindByKey(new object[] { rowPkeyGuid, 1, "Titre aer" }); Assert.Null(dmRow2); tbl2.CaseSensitive = false; var dmRow3 = tbl2.FindByKey(new object[] { rowPkeyGuid, 1, "Titre aer" }); Assert.NotNull(dmRow3); }
/// <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); }