■90313 / ) |
Re[10]: C# LINQ IEnumerableからDataTable |
□投稿者/ 魔界の仮面弁士 (2077回)-(2019/02/25(Mon) 15:57:11)
|
2019/02/25(Mon) 16:37:54 編集(投稿者)
■No90307 (魔界の仮面弁士) に追記 >>以下のように、条件テーブル:dtConditionと、チェック対象テーブル:dtMainがあったとして、 >>LINQのGroupBy拡張メソッドへ動的に値を指定したいのですが、 >> >> var q1 = from records in recSets >> group records by new { >> recCol01 = records.Field<string>(targetCol01), >> recCol02 = records.Field<string>(targetCol02), >> recCol03 = records.Field<string>(targetCol03) >> } into record >> select new { >> recKey = record.Key, >> recCount = record.Count() >> }; >> var targets = q1.Where(x => x.recCount > 1); > > どの部分を「動的」にしたいのでしょうか?
とりあえず、GroupBy のキーとして指定している匿名型を差し替えてみました。
var conditions = dtCondition.AsEnumerable().Select(r => r.Field<string>("Condition")).ToArray();
var q0 = dtMain.AsEnumerable().Select(row => conditions.Select(colName => row.Field<string>(colName)).ToArray());
var q1 = q0.GroupBy(items => new StringItems(items)).Select(r => new { recKey = r.Key.Items.ToArray(), recCount = r.Count() });
var targets2 = q1.Where(x => x.recCount > 1);
--- 上記の StringItems は、下記のクラス実装です。
// GroupBy キーの Equals メソッドの定義 public class StringItems { public ReadOnlyCollection<string> Items; public StringItems(string[] items) { Items = Array.AsReadOnly(items); } public override int GetHashCode() { return Items.Aggregate(0, (a, b) => a ^ b.GetHashCode()); } public override bool Equals(object other) { StringItems o = other as StringItems; return o == null ? false : o.Items.SequenceEqual(Items); } }
--- 匿名型の Equals では、「全てのプロパティが一致しているかどうか」で 一致判定が行われます。上記の StringItems クラスはそれを模倣したものです。
string[] keys1 = { "AA", "BB", "CC" }; string[] keys2 = { "AA", "BB", "CC" };
// 内容は同じでも、別のインスタンスなので「false」と判定されてしまう bool isSameKey1 = keys1.Equals(keys2);
// すべての文字列が同じ内容なので「true」 bool isSameKey2 = new StringItems(keys1).Equals(new StringItems(keys2));
|
|