private RowCollection CompareTables(Output targetOutput, Table targetTable, Table updatedTable, out TableOperation operation) { RowCollection rows = new RowCollection(); operation = TableOperation.None; // dropped tables if (null == updatedTable ^ null == targetTable) { if (null == targetTable) { operation = TableOperation.Add; rows.AddRange(updatedTable.Rows); } else if (null == updatedTable) { operation = TableOperation.Drop; } } else // possibly modified tables { SortedList updatedPrimaryKeys = new SortedList(); SortedList targetPrimaryKeys = new SortedList(); // compare the table definitions if (0 != targetTable.Definition.CompareTo(updatedTable.Definition)) { // continue to the next table; may be more mismatches this.OnMessage(WixErrors.DatabaseSchemaMismatch(targetOutput.SourceLineNumbers, targetTable.Name)); } else { this.IndexPrimaryKeys(targetTable, targetPrimaryKeys, updatedTable, updatedPrimaryKeys); // diff the target and updated rows foreach (DictionaryEntry targetPrimaryKeyEntry in targetPrimaryKeys) { string targetPrimaryKey = (string)targetPrimaryKeyEntry.Key; bool keepRow = false; RowOperation rowOperation = RowOperation.None; Row compared = this.CompareRows(targetTable, targetPrimaryKeyEntry.Value as Row, updatedPrimaryKeys[targetPrimaryKey] as Row, out rowOperation, out keepRow); if (keepRow) { rows.Add(compared); } } // find the inserted rows foreach (DictionaryEntry updatedPrimaryKeyEntry in updatedPrimaryKeys) { string updatedPrimaryKey = (string)updatedPrimaryKeyEntry.Key; if (!targetPrimaryKeys.Contains(updatedPrimaryKey)) { Row updatedRow = (Row)updatedPrimaryKeyEntry.Value; updatedRow.Operation = RowOperation.Add; updatedRow.SectionId = sectionDelimiter + updatedRow.SectionId; rows.Add(updatedRow); } } } } return(rows); }