Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 使用LINQ从一个表和另一个表中按字段删除重复项_.net_Linq_Ado.net_Datatable_Duplicate Removal - Fatal编程技术网

.net 使用LINQ从一个表和另一个表中按字段删除重复项

.net 使用LINQ从一个表和另一个表中按字段删除重复项,.net,linq,ado.net,datatable,duplicate-removal,.net,Linq,Ado.net,Datatable,Duplicate Removal,我必须在数据表中只保留数据库中当前不存在日期的记录 因此,我使用存储过程读取所有现有日期(正确吗?): 并将其加载到数据表中: var tableDate = new DataTable(); new SqlDataAdapter(command).Fill(tableDate); 现在如何从另一个表中删除所有不必要的行?我认为LINQ可能会有所帮助,但我不确定如何使用Except() 退货记录。日期除外 更新: 如果您的DataTable有键入的字段,则应如下所示: var excluded

我必须在
数据表中只保留数据库中当前不存在日期的记录

因此,我使用存储过程读取所有现有日期(正确吗?):

并将其加载到
数据表中

var tableDate = new DataTable();
new SqlDataAdapter(command).Fill(tableDate);
现在如何从另一个表中删除所有不必要的行?我认为
LINQ
可能会有所帮助,但我不确定如何使用
Except()

退货记录。日期除外

更新: 如果您的
DataTable
有键入的字段,则应如下所示:

var excluded=arbDates.Rows.OfType().Select(a=>a[0])
.Except(excDates.Rows.OfType().Select(e=>e[0])

否则你可以投下它:

var excluded=arbDates.Rows.OfType()
.Select(a=>Convert.ToDateTime(a[0].ToString())
.除了(
excDates.Rows.OfType()类型
.Select(e=>Convert.ToDateTime(e[0].ToString())

您可以使用
Except()

退货记录。日期除外

更新: 如果您的
DataTable
有键入的字段,则应如下所示:

var excluded=arbDates.Rows.OfType().Select(a=>a[0])
.Except(excDates.Rows.OfType().Select(e=>e[0])

否则你可以投下它:

var excluded=arbDates.Rows.OfType()
.Select(a=>Convert.ToDateTime(a[0].ToString())
.除了(
excDates.Rows.OfType()类型

.Select(e=>Convert.ToDateTime(e[0].ToString())

我在看你的答案,你说这很有效,你只想知道如何在“单个LINQ查询”中完成。请记住,这些查询都有延迟执行,因此以下两个查询在功能上是等效的:

var q =
    from d in dates
    select d.Field<DateTime>("date");
return
    (from r in records
     where !q.Contains(r.Field<DateTime>("date"))
     select r).CopyToDataTable();
(在本例中,只需将RemoveDuplicates方法中的“date”替换为“Code”)


希望其中一个能回答你的问题。否则,我认为您必须更清楚地了解您的需求。

我正在查看您的答案,您认为答案是有效的,您只想知道如何在“单个LINQ查询”中执行。请记住,这些查询都有延迟执行,因此以下两个查询在功能上是等效的:

var q =
    from d in dates
    select d.Field<DateTime>("date");
return
    (from r in records
     where !q.Contains(r.Field<DateTime>("date"))
     select r).CopyToDataTable();
(在本例中,只需将RemoveDuplicates方法中的“date”替换为“Code”)


希望其中一个能回答你的问题。否则,我认为您必须更清楚地了解您的需求。

您的SQL语句看起来不错。据我所知,您正在强制转换以从午夜开始获取默认时间值。因此,被比较的另一个表中的日期也必须与该格式匹配,以便将日期与中性时间进行比较。如果没有,您仍然可以使用下面的代码,但您必须在引用
tableResult
行字段的任何位置添加
.Date
属性。我还使用了
字段(0)
,但根据您的查询和前面的示例,您可能需要使用
字段(“日期”)

不需要自定义比较器。要将LINQ查询合并到单个查询中,只需使用
let
关键字,将中间结果带入查询并引用它

尝试一下:

var tableDate = new DataTable();
new SqlDataAdapter(command).Fill(tableDate);

// this is the other table that has other dates, so populate as needed
var tableResult = new DataTable();

var newTable =
    (from row in tableResult.AsEnumerable()
    let uniqueRows = tableResult.AsEnumerable().Select(r => r.Field<DateTime>(0))
                                .Except(tableDate.AsEnumerable().Select(r => r.Field<DateTime>(0)))
    where uniqueRows.Contains(row.Field<DateTime>(0))
    select row).CopyToDataTable();

您的SQL语句看起来不错。据我所知,您正在强制转换以从午夜开始获取默认时间值。因此,被比较的另一个表中的日期也必须与该格式匹配,以便将日期与中性时间进行比较。如果没有,您仍然可以使用下面的代码,但您必须在引用
tableResult
行字段的任何位置添加
.Date
属性。我还使用了
字段(0)
,但根据您的查询和前面的示例,您可能需要使用
字段(“日期”)

不需要自定义比较器。要将LINQ查询合并到单个查询中,只需使用
let
关键字,将中间结果带入查询并引用它

尝试一下:

var tableDate = new DataTable();
new SqlDataAdapter(command).Fill(tableDate);

// this is the other table that has other dates, so populate as needed
var tableResult = new DataTable();

var newTable =
    (from row in tableResult.AsEnumerable()
    let uniqueRows = tableResult.AsEnumerable().Select(r => r.Field<DateTime>(0))
                                .Except(tableDate.AsEnumerable().Select(r => r.Field<DateTime>(0)))
    where uniqueRows.Contains(row.Field<DateTime>(0))
    select row).CopyToDataTable();

据我所知,您正在尝试对来自某个导入的数据进行重复数据消除。您可能不需要使用LINQ执行此操作。尽管文章标题建议使用LINQ,但您稍后会质疑LINQ是否是最好的解决方案,根据我们所知,我认为您可以使用单个Insert语句来实现这一点

首先,我建议将数据批量复制到数据库中的临时位置(如果您还没有这样做的话),如下所示:

大容量复制到临时位置的优点之一是可以添加索引等,以加快清理过程。要消除重复数据,您可以运行如下查询:

Insert DestinationData(...)
Select ...
From BulkCopyData As BCD
Where Id = (
            Select Min(BCD2.[Id])
            From BulkCopyData As BCD2
            Where Cast(BCD2.[Date] As Date) = Cast(BCD.[Date] As Date)
            )


这将提取它找到的第一个日期(Id最低的日期)。这显然有些武断,但为了更精确,我们需要更多地了解数据结构和要求。

据我所知,您正在尝试对来自某个导入的数据进行重复数据消除。您可能不需要使用LINQ执行此操作。尽管文章标题建议使用LINQ,但您稍后会质疑LINQ是否是最好的解决方案,根据我们所知,我认为您可以使用单个Insert语句来实现这一点

首先,我建议将数据批量复制到数据库中的临时位置(如果您还没有这样做的话),如下所示:

大容量复制到临时位置的优点之一是可以添加索引等,以加快清理过程。要消除重复数据,您可以运行如下查询:

Insert DestinationData(...)
Select ...
From BulkCopyData As BCD
Where Id = (
            Select Min(BCD2.[Id])
            From BulkCopyData As BCD2
            Where Cast(BCD2.[Date] As Date) = Cast(BCD.[Date] As Date)
            )


这将提取它找到的第一个日期(Id最低的日期)。这显然有点武断,但为了更精确,我们需要更多地了解数据结构和需求。

Hi。你能帮我写一个LINQ查询吗
var newTable = tableResult.AsEnumerable()
    .Select(row => new
    {
        Row = row,
        UniqueRows =  tableResult.AsEnumerable()
                                 .Select(r => r.Field<DateTime>(0))
                                 .Except(tableDate.AsEnumerable().Select(r => r.Field<DateTime>(0)))
    })
    .Where(item => item.UniqueRows.Contains(item.Row.Field<DateTime>(0)))
    .Select(item => item.Row)
    .CopyToDataTable();
var commonDates = tableDate.AsEnumerable().Select(row => row.Field<DateTime>(0))
                           .Intersect(tableResult.AsEnumerable().Select(row => row.Field<DateTime>(0)));

for (int index = tableResult.Rows.Count - 1; index >= 0; index--)
{
    if (commonDates.Contains(tableResult.Rows[index].Field<DateTime>(0)))
    {
        tableResult.Rows.RemoveAt(index);
    }
}
Create Table TempBulkCopyData
(
    Id int not null identity(1,1)
    , Date DateTime2 not null
    , ...
)
Insert DestinationData(...)
Select ...
From BulkCopyData As BCD
Where Id = (
            Select Min(BCD2.[Id])
            From BulkCopyData As BCD2
            Where Cast(BCD2.[Date] As Date) = Cast(BCD.[Date] As Date)
            )
Insert DestinationData(...)
Select ...
From BulkCopyData As BCD
Where Id = (
            Select Min(BCD2.[Id])
            From BulkCopyData As BCD2
            Where DateDiff(d, BCD.[Date], BCD2.[Date]) = 0
            )