2017-10-07 41 views
0

問題:如果在將源數據表合併到實際數據表(ActualDT.Merge(SourceDT))時主鍵大於現有的,則只插入行。我下面的問題如何僅在主鍵大於最後一個主鍵時填充DataTable行?

詳情:

我填與從外部服務器API的Int64主鍵的實際數據表反序列化JSON到源數據表後。然後,我將DataTable中的行寫入數據庫,並清除DataTable中除最大主鍵以外的所有行。後來我從API請求新的數據,並且通常響應包含我已經寫入數據庫並從DataTable清除的相同行。

如果我不清理DataTable行,性能下降,它是記憶豬。所以,我在清潔後留下一排最大的主鑰匙。

我不想在合併之前比較Source DataTable中的每個PrimaryKey,比較可能需要很長時間。

我應該怎麼做才能防止合併我已寫入數據庫並從Actual DataTable中刪除的行?也許我可以在反序列化過程中排除它們(我使用NewtonSoft JSON.net)?或者任何簡單的方法來防止合併行,如果他們的主鍵<實際DataTable的主鍵?

感謝您的回答!

UPDATE:合併代碼

public class MyData 
{ 
    DataTable BlackPairs = new DataTable(); 
    DataTable WhiteTable = new DataTable(); 

    public string _Json { 

     set 
     { 
      DataSet TempDS = JsonConvert.DeserializeObject<DataSet>(value); 
      try 
      { 
       foreach (DataTable table in TempDS.Tables) 
       { 
        BlackPairs = table.Copy(); 
        WhiteTable.Merge(BlackPairs); 
       } 
      }catch{} 
     } 
    } 

    public MyData() 
    { //columns initialization 
     WhiteTable.Columns.AddRange(new DataColumn[]{columns); 
     WhiteTable.PrimaryKey = new DataColumn[]{tid}; 
    } 
+0

你可以發佈'merge function'代碼。你可以使它在裏面 –

+0

@AleksaRistic,我有更新後的例子 –

+0

需要'合併功能'代碼 –

回答

0

我已經創建基礎上,我們已經通過評論談到定製Merge功能。此功能僅在主列是typeof(int)但它可以很容易地改進以獲得各類或者只是改變它,你需要什麼類型(字符串,整數,布爾...)以上

public Test() 
{ 
    InitializeComponent(); 
    DataTable smallerDatatable = new DataTable(); 
    smallerDatatable.Columns.Add("Col1", typeof(int)); 
    smallerDatatable.Columns.Add("Col2", typeof(string)); 

    DataTable biggerDatatable = new DataTable(); 
    biggerDatatable.Columns.Add("Col1", typeof(int)); 
    biggerDatatable.Columns.Add("Col2", typeof(string)); 

    smallerDatatable.Rows.Add(1, "Row1"); 
    smallerDatatable.Rows.Add(2, "Row2"); 
    smallerDatatable.Rows.Add(3, "Row3"); 
    biggerDatatable.Rows.Add(1, "Row1"); 
    biggerDatatable.Rows.Add(2, "Row2"); 
    biggerDatatable.Rows.Add(3, "Row3"); 
    biggerDatatable.Rows.Add(4, "Row4"); 
    biggerDatatable.Rows.Add(5, "Row5"); 

    DataTable mergedTable = MergeOnUniqueColumn(smallerDatatable, biggerDatatable, "Col1"); 
    dataGridView1.DataSource = mergedTable; 
} 

private DataTable MergeOnUniqueColumn(DataTable smallTable, DataTable bigTable, string uniqueColumn) 
{ 
    DataTable m = smallTable; 
    for(int i = 0; i < bigTable.Rows.Count; i++) 
    { 
     if(!(smallTable.AsEnumerable().Any(row => bigTable.Rows[i][uniqueColumn].Equals(row.Field<object>(uniqueColumn))))) 
     { 
      smallTable.Rows.Add(bigTable.Rows[i].ItemArray); 
     } 
    } 
    return m; 
} 

功能將填補每從bigTable丟失smallTable內的唯一值。

如果你想填寫smallTable的值從bigTable只有在最後smallTable行後,然後使用此功能。

private DataTable MergeOnUniqueColumnAfterLastID(DataTable smallTable, DataTable bigTable, string uniqueColumn) 
{ 
    DataTable m = smallTable; 
    int maxUnique = Convert.ToInt32(m.Compute("max([" + uniqueColumn + "])", string.Empty)); 
    for (int i = 0; i < bigTable.Rows.Count; i++) 
    { 
     if (!(smallTable.AsEnumerable().Any(row => (int)bigTable.Rows[i][uniqueColumn] <= maxUnique))) 
     { 
      smallTable.Rows.Add(bigTable.Rows[i].ItemArray); 
     } 
    } 
    return m; 
} 
+0

如果'smallerDataTable'不存在Row1和Row2,它仍然合併Row1和Row2到'smallerDataTable' from'largerDataTable'。我看起來很活潑,可以從smallDataTable中清理Row1和Row2,並且只能在Row3之後粘貼來自'biggerDataTable'的行。 –

+0

如果我得到它,你不想插入只有'uniqueColumn'值不存在'smallTable'中,但只有當它大於'smallTable max uniqueColumn value'時纔會插入? –

+0

@ИванПогосов我編輯了答案,並添加了新的功能,您將使用而不是舊的 –