C# 从另一个datatable中删除datatable中的行

C# 从另一个datatable中删除datatable中的行,c#,.net,datatable,C#,.net,Datatable,我有两个数据表:allRows和rowsToDelete。我想从rowsToDelete包含的allRows中删除行。两个表都有相同的结构(相同的列及其数据类型),但我不知道确切的列名,甚至不知道它们的数量 object.Equals()方法将不同表中的行识别为不相等,因此我不能使用这种方法 通过谷歌搜索和阅读StackOverflow,我有了一个想法,也许它甚至可以在一行中完成,但我不知道如何为这种情况建立条件: allRows = allRows.AsEnumerable().Where(?

我有两个数据表:
allRows
rowsToDelete
。我想从
rowsToDelete
包含的
allRows
中删除行。两个表都有相同的结构(相同的列及其数据类型),但我不知道确切的列名,甚至不知道它们的数量

object.Equals()
方法将不同表中的行识别为不相等,因此我不能使用这种方法

通过谷歌搜索和阅读StackOverflow,我有了一个想法,也许它甚至可以在一行中完成,但我不知道如何为这种情况建立条件:

allRows = allRows.AsEnumerable().Where(???).CopyToDataTable();

我不知道你的数据结构,但一般来说你可以

var cleanedUp = allRows.Where(row => !rowsToDelete.Any(row2 => row2.Id == row.Id ));

如果您没有任何主键,请检查组合(复合键)为您提供唯一性的多个列,您可以从rowsTodelete表中存在相似数据的所有行中轻松删除行。

首先在相似列上的两个表之间实现内部联接,以检索要删除的数据,并将其插入任何临时表中,然后从allrows表中删除此数据


希望这将对您有所帮助。

此解决方案适用于任何数据结构、任何列的编号和类型。 我们将数据行表示为数组,并比较每个单元格

public static void DeleteCopies(DataTable allRows, DataTable rowsToDelete)
    {
        foreach (DataRow rowToDelete in rowsToDelete.Rows)
        {
            foreach (DataRow row in allRows.Rows)
            {
                var rowToDeleteArray = rowToDelete.ItemArray;
                var rowArray = row.ItemArray;
                bool equalRows = true;
                for (int i = 0; i < rowArray.Length; i++)
                {
                    if (!rowArray[i].Equals(rowToDeleteArray[i]))
                    {
                        equalRows = false;
                    }                            
                }
                if (equalRows)
                {
                    allRows.Rows.Remove(row);
                    break;
                }
            }
        }
    }
publicstaticvoiddeletecompions(DataTable allRows,DataTable rowsToDelete)
{
foreach(rowsToDelete.Rows中的DataRow rowtodele)
{
foreach(allRows.Rows中的DataRow行)
{
var rowToDeleteArray=rowToDelete.ItemArray;
var rowArray=row.ItemArray;
bool equalRows=true;
for(int i=0;i
您的任务没有解决方案,您更改了条件, 首先你写:

两个表具有相同的结构(相同的列及其数据类型)

然后你写:


这就是问题所在-结构可以不同,并且不能有“Id”列

如果您甚至可以更改数据,您可以减去这两个表并研究它们的结构、列等,但您坚持不知道它们

当你找到结构时,任务就变得很简单,就像这样(我使用我自己项目中的结构):

var foo=DbContext
.Set()
.Select(x=>new{x.assignment,x.Availability})
.ToList();
var foo2=DbContext
.Set()
.选择(x=>x)
.ToList();
var bar=foo2.Where(x=>foo.Select(y=>y.assignment).Contains(x.assignment)
&&选择(y=>y.Availability).Contains(x.Availability));
DbContext.RemoveRange(bar);
DbContext.SaveChanges();

你可以写得更优雅,但问题很明显

结构可能不同,如果你阅读问题,就不会有“Id”栏,用户不知道列及其类型,但我认为用户有权通过select查询从那里访问数据库,他可以轻松访问列名称。我想这不是解决方法,但我认为在这种情况下,如果使用首先,您必须至少列出列名。如果表存在,那么您可以轻松地使用select语句来查找列名,不是吗?我的意思是,它有时可能会不同,但无论如何,这两个表都是一样的。我想您只是试图获得一些投票,而不是解决您的问题。这不是现实生活中的应用程序,你的解决方案证明了这一点:首先-SequenceEqual(如果你没有重新定义它们)比较引用,而不是数据(很明显,即使数据是相等的,也会得到false),甚至它是同一类型的第二,伙计,真的,你只需要使用表的结构并通过linq内联,如果你有权访问DB,您可以得到表的结构。ох уж эти братья славяне... какой пассаж.;)它是从用户的.dbf文件中提取数据表的真实应用程序,这就是为什么它的结构是unknown@GlebGlazyrin解决了这个问题
var foo = DbContext
            .Set<Task>()
            .Select(x => new{x.Assignee, x.Availability})
            .ToList();

        var foo2 = DbContext
            .Set<Task2>()
            .Select(x => x)
            .ToList();

        var bar = foo2.Where(x => foo.Select(y => y.Assignee).Contains(x.Assignee) 
                                  && foo.Select(y => y.Availability).Contains(x.Availability));

        DbContext.RemoveRange(bar);
        DbContext.SaveChanges();