私はあなたがうまくいくとあなたが言うあなたの答えを見ています、そしてあなたはただ「単一のLINQクエリ」でそれをする方法を知りたいだけです。これらのクエリはすべて実行が延期されているため、次の2つのクエリは機能的に同等であることに注意してください。
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();
2番目のバージョンは読みにくいですが、それでも「1つのクエリ」です。
そうは言っても、これらの例はどれも質問のタイトルと実際には一致していないようです。これは、重複する行を削除しようとしていることを示しています。それが本当にあなたがやろうとしていることであるならば、これはそれをする方法です:
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
(この例のメソッドでは、「date」を「Code」に置き換えるだけです)
うまくいけば、これらの1つがあなたの質問に答えます。そうでなければ、あなたはあなたの要件をより明確にする必要があると思います。