2017-10-07 59 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

@ИванПогосов我编辑了答案,并添加了新的功能,您将使用而不是旧的 –