表没有主键c#

本文关键字: | 更新日期: 2023-09-27 18:13:41

我试图从DataTable AllItemsDataTables Items行删除行;这样做的目的是从DataTable AllItems中获取不在DataTable Items中的项目

所有这些行都来自同一个Excel文件,包含几个列,并且是相等的。

我已经尝试使用foreach循环:

foreach(DataRow dr in AllItems.Rows)
{
if (Items.Contains(dr))
{
AllItems.Rows.Remove(dr);
}

但是我得到以下错误:表没有主键。

有人知道我如何删除这些行吗?

表没有主键c#

您有几个选择:

1。添加主键

您可以在创建数据表时添加主键。

假设你有一个名为"Id"的列,那么你可以这样做:

AllItems.PrimaryKey = new DataColumn[] { workTable.Columns["Id"] };} 
或者,对于主键是组合键(多列)的情况:
AllItems.PrimaryKey = new DataColumn[] { 
                             workTable.Columns["Id"], 
                             workTable.Columns["Name"] };} 

这将允许Contains正常工作。

2。使用DataView

可以使用DataView过滤出不同的行;

DataView view = new DataView(AllItems);
DataTable distinctValues = view.ToTable(true, "Column1", "Column2" , ..., "ColumnN");

3。使用Select

查找匹配行

或者您可以依靠Select方法来测试Items数据表中是否存在相应的行,基于类似SQL的where子句:

List<DataRow> rowsToRemove = new List<DataRow>();
foreach(DataRow allItemRow in AllItems.Rows)
{
    if(Items.Select(String.Format("Id = {0}"), 
          allItemRow.Field<Int32>("Id")).Length == 0)
    {
        rowsToRemove.Add(allItemRow);
    }
}
rowsToRemove.ForEach(x => x.Delete());
AllItems.AcceptChanges();

注意重要的是不要在迭代AllItems中的rows集合时删除行-相反,收集这些行,然后删除它们。

4。

中的路上过滤器

还请注意,我还没有尝试过,但是,取决于你如何选择Excel中的行,你可以使用SQL DISTINCT子句;如果您使用ODBC从Excel中加载数据,那么您可以尝试在源处进行过滤。

你可以试试:

var exceptItems = AllItems.Rows.Cast<DataRow>()
    .Except(Items.Rows.Cast<DataRow>(), DataRowComparer.Default)
    .ToList();

作为另一种选择,如果您希望在删除items行之后继续使用allItems数据表,您可以尝试以下操作(假设两个数据表中都有Id列,它唯一标识每个数据表中的一行):

var exceptItems = AllItems.Rows.Cast<DataRow>()
    .Select((i, index) => new { id = i["Id"], index })
    .Intersect(Items.Rows.Cast<DataRow>()
        .Select((i, index) => new { id = i["Id"], index }))
    .ToList();
for (int i = exceptItems.Count()-1; i >= 0; i--)
{
    AllItems.Rows.RemoveAt(exceptItems[i].index);
}

下面是上面最后一个例子的更好的安排:

AllItems.Rows.Cast<DataRow>()
    .Select((i, index) => new { id = i["Id"], index })
    .Intersect(Items.Rows.Cast<DataRow>()
        .Select((i, index) => new { id = i["Id"], index }))
    .OrderByDescending(i => i.index)
    .ToList()
    .ForEach(i => AllItems.Rows.RemoveAt(i.index));
相关文章:
  • 没有找到相关文章