问题:在将源DataTable合并到实际DataTable(ActualDT.Merge(SourceDT)
)时,仅插入行如果主键大于现有。
我的问题详情如下:
在将JSON反序列化为Source DataTable后,我从外部服务器用API填充带有Int64
主键的Actual DataTable。然后我将DataTable中的行写入我的数据库并清除DataTable中除最大主键之外的所有行。后来我从API请求新数据,并且响应通常包含我已写入数据库的相同行以及从我的DataTable清理。
如果我不清理DataTable行,性能下降,它就是内存猪。因此,我在清理后留下一行最大的主键。
我不想在合并之前比较Source DataTable中的每个PrimaryKey,比较可能需要花费很多时间。
如何防止合并已写入数据库并从Actual DataTable中删除的行?也许我可以在反序列化过程中排除它们(我使用NewtonSoft JSON.net)?或者任何zippy方法来防止合并行,如果他们的主键< Actual DataTable中的主键?
感谢您的回答!
更新:合并代码
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 :(得分:0)
我已根据我们通过评论讨论的内容创建了自定义Merge
功能。此函数仅在主列为typeof(int)
时才有效,但可以轻松改进以获取所有类型或仅将其更改为您需要的类型(string,int,bool ...)
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;
}
上面的函数将填充smallTable
中bigTable
内的每个缺失的唯一值。
如果您希望仅在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;
}