首页 文章

仅当主键大于上一个主键时,如何填充DataTable行?

提问于
浏览
0

问题:在将源DataTable合并到实际DataTable( ActualDT.Merge(SourceDT) )时仅插入 if primary key is bigger than existing one 行 .

我的问题详情如下:

在将JSON反序列化为Source DataTable后,我从外部服务器用API填充了一个带有 Int64 主键的Actual DataTable . 然后我将DataTable中的行写入我的数据库并清除DataTable中除最大主键之外的所有行 . 后来我从API请求新数据,并且响应通常包含我已经写入数据库的相同行以及从我的DataTable清理 .

如果我不清理DataTable行,性能下降,它的内存猪 . 因此,我在清洁后留下一行最大的主键 .

我不想在合并之前比较Source DataTable中的每个PrimaryKey,比较可能需要花费很多时间 .

我该怎么做才能防止合并我已写入数据库并从Actual DataTable中删除的行?也许我可以在反序列化过程中排除它们(我使用NewtonSoft JSON.net)?或者,如果它们的主键<Actual DataTable中的主键,则阻止合并行的任何zippy方法?

谢谢你的回答!

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

1 回答

  • 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;
    }
    

相关问题