public static void UpdateMd5Old(List <Md5Result> changedMd5, int tableID, SqlConnection Conn, DamaiDataSet.SyncMD5OldDataTable table) { // string sqlCmd = "Select * from SyncMd5Old Where TableID=" + tableID.ToString(); // 必需和 CalcCompMd5 內一致 var dic = new Dictionary <Guid, DamaiDataSet.SyncMD5OldRow>(); //加速用 foreach (var r in table) { if (r.RowState == DataRowState.Deleted) { continue; } dic.Add(r.PrimaryKey, r); } foreach (var md5 in changedMd5) { if (md5.Status == DB.RowStatus.Unchanged) { continue; } DamaiDataSet.SyncMD5OldRow row = null; dic.TryGetValue(md5.PrimaryKey, out row); if (md5.Status == DB.RowStatus.Deleted) { if (row != null) { row.Delete(); } } else { if (row == null) { row = table.NewSyncMD5OldRow(); row.ID = Guid.NewGuid(); row.MD5 = md5.Md5Now; row.PrimaryKey = md5.PrimaryKey; row.TableID = tableID; table.AddSyncMD5OldRow(row); } else { row.MD5 = md5.Md5Now; } } } var adapter = new DamaiDataSetTableAdapters.SyncMD5OldTableAdapter(); adapter.Connection = Conn; //adapter.Adapter.SelectCommand = new SqlCommand(sqlCmd); // 此行無效,因為Update或Fill的預設動作,都會被蓋掉,看 try { adapter.Update(table); } catch { } }
static public Dictionary <Guid, Md5Result> CalcCompMd5(DB.TableInfo tableInfo, SqlConnection conn, ref DataSet dataSet, ref DamaiDataSet.SyncMD5OldDataTable tableMd5Old) { int tableID = tableInfo.TableID; if (tableID == int.MinValue) { return(null); } string tableName = tableInfo.Name; // 判斷主Key型態 List <SqlColumnStruct> listStruct = tableInfo.Struct; PrimaryKeyType PKType = GetFirstKeyType(listStruct); if (PKType == PrimaryKeyType.Unknown) { return(null); } // 載入Old var adapterOld = new DamaiDataSetTableAdapters.SyncMD5OldTableAdapter(); adapterOld.Connection = conn; var dicResult = new Dictionary <Guid, Md5Result>(); //byte[] FileMd5Old=null; try { // Fill的預設動作,因為他會自設SelectCommand,所以只好自己寫一次 var SqlCmd = new SqlCommand("Select * from SyncMd5Old Where TableID=" + tableID.ToString(), conn); SqlCmd.CommandType = CommandType.Text; adapterOld.Adapter.SelectCommand = SqlCmd; tableMd5Old.Clear(); adapterOld.Adapter.Fill(tableMd5Old); ////////////////////////////////////// foreach (var row in tableMd5Old) { if (row.IsMD5Null()) { row.Delete(); continue; } // 資料庫內md5是dbnull,不應該 if (row.IsPrimaryKeyNull()) { row.Delete(); continue; } Md5Result result = new Md5Result(); result.PrimaryKey = row.PrimaryKey; result.Md5Old = row.MD5; result.Status = RowStatus.Deleted; switch (PKType) { case PrimaryKeyType.DateTime: case PrimaryKeyType.IntCombined: case PrimaryKeyType.String: case PrimaryKeyType.UniqueIdentifier: dicResult.Add(result.PrimaryKey, result); break; default: return(null); } } } catch (Exception ex) { throw ex; } // 計算New MD5 MD5Provider = new MD5CryptoServiceProvider(); SqlDataAdapter adapterNow = new SqlDataAdapter("Select * From [" + tableName + "]", conn); adapterNow.MissingSchemaAction = MissingSchemaAction.AddWithKey; DataTable tableNow = new DataTable(tableName); // dataSet.Tables.Add(tableNow); // adapterNow.Fill(dataSet, tableName); // 這三行一定要這樣寫才會自動填 Columns,一定要指定tableName,而且要存在,要不然會新建一個叫'Table' if (tableName == "Order") // [Order]的MD5量大,是由AP計算的 { DataTable table = new DataTable(); try { //adapterNow.Fill(tableNow); // 填MD5Now入listResult foreach (DataRow row in tableNow.Rows) { byte[] bts = new byte[16]; IntToBinary16((int)row["ID"], ref bts, 0); Guid pk = new Guid(bts); Md5Result val; if (dicResult.TryGetValue(pk, out val)) { val.Md5Now = (byte[])row["MD5"]; if (!val.SameMd5()) { val.Status = RowStatus.Changed; } else { val.Status = RowStatus.Unchanged; } } else { val = new Md5Result(); val.PrimaryKey = pk; val.Md5Old = null; val.Md5Now = (byte[])row["MD5"]; val.Status = RowStatus.New; dicResult.Add(pk, val); } } } catch (Exception ex) { throw ex; } } else { try { List <RunningSet> Runnings = new List <RunningSet>(); if (tableInfo.Childs != null) { foreach (var child in tableInfo.Childs) { Runnings.Add(new RunningSet(child)); } } foreach (var run in Runnings) { ChildInfo info = run.childInfo; run.adapter = new SqlDataAdapter("Select * From [" + info.Name + "]", conn); run.table = new DataTable(info.Name); dataSet.Tables.Add(run.table); run.childType = GetFirstKeyType(info.Struct); run.adapter.Fill(dataSet, info.Name); run.relation = new DataRelation(info.ForeignKeyName, tableNow.Columns[info.FatherKey], run.table.Columns[info.ChildKey]); dataSet.Relations.Add(run.relation); } foreach (DataRow row in tableNow.Rows) { byte[] pk; StringBuilder strBuilder = Row2Str(row, listStruct, PKType, MD5Provider, out pk); if (strBuilder == null) { return(null); } foreach (var run in Runnings) { if (run.relation == null) { continue; } DataRow[] childRows = row.GetChildRows(run.relation); byte[] childPK; foreach (DataRow childRow in childRows) { strBuilder.Append(Row2Str(childRow, run.childInfo.Struct, run.childType, MD5Provider, out childPK)); } } byte[] md5 = MD5Provider.ComputeHash(Encoding.Unicode.GetBytes(strBuilder.ToString())); // 還沒考慮Detail Guid pkGuid = new Guid(pk); Md5Result val; if (dicResult.TryGetValue(pkGuid, out val)) { val.Md5Now = md5; if (!val.SameMd5()) { val.Status = RowStatus.Changed; } else { val.Status = RowStatus.Unchanged; } } else { val = new Md5Result(); val.PrimaryKey = pkGuid; val.Md5Old = null; val.Md5Now = md5; val.Status = RowStatus.New; dicResult.Add(pkGuid, val); } } // 更新SyncTable內容 tableInfo.RecordCount = tableNow.Rows.Count; // syncTableRow.MD5 = ??? File MD5待寫 } catch (Exception ex) { throw ex; } } return(dicResult); }