【问题标题】:How to fill DataTable rows only if primary key is bigger than last primary key?仅当主键大于最后一个主键时如何填充 DataTable 行?
【发布时间】:2017-10-07 13:12:30
【问题描述】:

问题:在将源 DataTable 合并到实际 DataTable (ActualDT.Merge(SourceDT)) 时,仅当主键大于现有主键时才插入行。

我的问题详情如下:

在将 JSON 反序列化为源数据表后,我通过来自外部服务器的 API 使用 Int64 主键填充实际数据表。然后我将数据表中的行写入我的数据库并清除数据表中的所有行,除了最大的主键。后来我从 API 请求新数据,并且响应通常包含我已经写入数据库并从我的 DataTable 中清除的相同行。

如果我不清理 DataTable 行,性能会下降,而且是内存猪。所以,我在清理后留下最大主键的一行。

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

我应该怎么做才能防止合并我已经写入数据库并从实际数据表中删除的行?也许我甚至可以在反序列化过程中排除它们(我使用 NewtonSoft JSON.net)?或者,如果它们的主键

感谢您的回答!

更新:合并代码

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

【问题讨论】:

  • 您能发布merge function 代码吗?你可以把它放在里面
  • @AleksaRistic,我有更新帖子的例子
  • 需要merge function代码
  • @AleksaRistic, WhiteTable.Merge(BlackPairs);这是合并函数,C# 中 System.Data 的标准。或者你的意思是什么功能?
  • 还有一个问题。两个表中的列是否相同?

标签: c# json datatable


【解决方案1】:

根据我们通过 cmets 讨论的内容,我创建了自定义 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;
}

【讨论】:

  • 如果smallerDataTable 不存在Row1 和Row2,它仍然将Row1 和Row2 从biggerDataTable 合并到smallerDataTable。我看起来很快捷地从 smallDataTable 中清除 Row1 和 Row2 并仅在 Row3 之后粘贴来自 biggerDataTable 的行。
  • 如果我明白了,您不想插入仅当uniqueColumn 值在smallTable 中不存在但仅当它大于smallTable max uniqueColumn value 时才插入?
  • @ИванПогосов 我已编辑答案并添加了您将使用的新功能,而不是旧功能
  • 是的 :-) col1 int 还会增加随机值(1000 之后可以到 1020,而不是 1001)。对于smallerTable中的示例 col1.row1=1, col1.row2=3, col1.row3 = 10;如果 largeDataTable 包含行 col1.row1=9 和 col2.row2=12,则只需将 col1.row2 从 largeDataTable 合并到 smallDataTable。结果,smallerDataTable 将包含 row1=1、row=3、row3=10、row4=12。
  • 看起来不错的解决方案!至少它在起作用:) 我稍后会测量性能,也许我可以改进它。非常感谢你!
猜你喜欢
  • 1970-01-01
  • 2016-11-30
  • 1970-01-01
  • 2016-04-08
  • 2019-12-29
  • 2019-02-16
  • 2013-04-30
  • 1970-01-01
  • 2019-03-03
相关资源
最近更新 更多