我正在查看您的答案,您说它有效,您只想知道如何在“单个 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();
和:
return
(from r in records
where !dates
.Select(d => d.Field<DateTime>("date"))
.Contains(r.Field<DateTime>("date"))
select r).CopyToDataTable();
第二个版本更难阅读,但是,它是“一个查询”。
话虽如此,这些示例似乎都与您的问题标题不匹配,这表明您正在尝试删除重复行。如果这确实是你想要做的,这里有一个方法可以做到这一点:
static DataTable RemoveDuplicates(DataTable dt)
{
return
(from row in dt.Rows.OfType<DataRow>()
group row by row.Field<string>("date") into g
select g
.OrderBy(r => r.Field<int>("ID"))
.First()).CopyToDataTable();
}
如果您不关心删除了哪些重复项,则可以删除该OrderBy
行。您可以按如下方式进行测试:
static void Main(string[] args)
{
using (DataTable original = CreateSampleTable())
using (DataTable filtered = RemoveDuplicates(original))
{
DumpTable(filtered);
}
Console.ReadKey();
}
static DataTable CreateSampleTable()
{
DataTable dt = new DataTable();
dt.Columns.Add("ID", typeof(int));
dt.Columns.Add("Code", typeof(string));
dt.Columns.Add("Name", typeof(string));
dt.Rows.Add(1, "123", "Alice");
dt.Rows.Add(2, "456", "Bob");
dt.Rows.Add(3, "456", "Chris");
dt.Rows.Add(4, "789", "Dave");
dt.Rows.Add(5, "123", "Elen");
dt.Rows.Add(6, "123", "Frank");
return dt;
}
static void DumpTable(DataTable dt)
{
foreach (DataRow row in dt.Rows)
{
Console.WriteLine("{0},{1},{2}",
row.Field<int>("ID"),
row.Field<string>("Code"),
row.Field<string>("Name"));
}
}
RemoveDuplicates
(只需将本例方法中的“日期”替换为“代码”即可)
希望其中之一能回答您的问题。否则我认为你将不得不更清楚你的要求。