如果主键大于上一个主键,如何填充DataTable行?

时间:2017-10-07 13:12:30

标签: c# json datatable

问题:在将源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};
    }

1 个答案:

答案 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;
}

上面的函数将填充smallTablebigTable内的每个缺失的唯一值。

如果您希望仅在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;
}