|
■No99699 (河童 さん) に返信
> データベースから取得したデータをリストにセット。
> そのリストからさらに集計用選択リストを作成したいと思っています。
(1) koumoku1Num ではなく koumokuNum という非対称的な項目名なのは仕様ですか?
(2) KoumokuData に引数付きコンストラクターをオーバーロードしておいた方が楽ですよ。
(3) サンプル作成の「void CreateKirokuLst()」は、フィールド変数へ依存しないよう、
「List<KirokuSelected> CreateKirokuLst(List<KoumokuData> koumokuDataLst)」
とした方が入出力対象が明確になると思います。
…というのは本題ではないので放置して:
> 記録がない場合は「空白」
null ではなく "" にするということですかね?
> // 条件:記録番号が「1」「2」「3」3種類
実際は上記のほか、区切りとして無視される "0" が混入しているようですが、
万が一 "0", "1", "2", "3" 以外が来た場合は、エラー扱いで良いですよね?
> 集計用選択リストは、データリストの「Koumoku2Num」が変わったときに、
> 「KirokuNum」を条件として作成したいです。
kiroku 以外の id,date,KoumokuNum,Koumoku2Num,Koumoku3Num,KirokuNum までが主キーなのですよね?
だとしたら、Koumoku2Num までが同じで、Koumoku3Num が異なっていた場合が
未定義となっています。たとえば下記のような場合の集計結果が曖昧です。
id date KoumokuNum Koumoku2Num Koumoku3Num KirokuNum kiroku
1001 20220510 3 2 1 0
1001 20220510 3 2 1 1 10
1001 20220510 3 2 3 0
1001 20220510 3 2 3 1 15
1001 20220510 3 2 3 2 14
ひとまず今回は Koumoku3Num が "1" 固定のようでしたので、
主キーが id,date,KoumokuNum,Koumoku2Num,Koumoku3Num,KirokuNum の場合と
主キーが id,date,KoumokuNum,Koumoku2Num,KirokuNum の場合で結果は同じですが…。
public List<KoumokuData> KoumokuDataLst;
public List<KirokuSelected> KirokuSelectedLst;
void CreateKirokuLst()
{
// サンプル記録データ(テーブルのデータをリストにセット)
var KoumokuDataLst = new List<KoumokuData>();
// サンプルを作りやすいよう、KoumokuData クラスには
// 引数付きのコンストラクターもオーバーロードしてあります。
// public KoumokuData()
// public KoumokuData(string id, string date, string koumokuNum, string koumoku2Num, string koumoku3Num, string kirokuNum, string kiroku)
KoumokuDataLst.Add(new KoumokuData("1001", "20220510", "3", "2", "1", "0", "" ));
KoumokuDataLst.Add(new KoumokuData("1001", "20220510", "3", "2", "1", "1", "10" ));
KoumokuDataLst.Add(new KoumokuData("1001", "20220510", "3", "2", "1", "2", "9" ));
KoumokuDataLst.Add(new KoumokuData("1001", "20220510", "3", "2", "1", "3", "100"));
KoumokuDataLst.Add(new KoumokuData("1001", "20220510", "3", "4", "1", "0", "" ));
KoumokuDataLst.Add(new KoumokuData("1001", "20220510", "3", "4", "1", "1", "8" ));
KoumokuDataLst.Add(new KoumokuData("1001", "20220510", "3", "4", "1", "2", "7" ));
KoumokuDataLst.Add(new KoumokuData("1001", "20220510", "3", "4", "1", "3", "200"));
KoumokuDataLst.Add(new KoumokuData("1001", "20220515", "3", "2", "1", "0", "" ));
KoumokuDataLst.Add(new KoumokuData("1001", "20220515", "3", "2", "1", "1", "6" ));
KoumokuDataLst.Add(new KoumokuData("1001", "20220515", "3", "2", "1", "2", "5" ));
KirokuSelectedLst = new List<KirokuSelected>();
// 選択記録データのリスト側の主キーが、4 つなのか 5 つなのかが現仕様からは読み取れませんでした。
// そのため今回は、koumoku2Num だけでなく koumoku3Num もグループ化しています
var dict = new Dictionary<(string id, string date, string koumokuNum, string koumoku2Num, string koumoku3Num), KirokuSelected>();
KoumokuDataLst.GroupBy(x =>
{
// Dictionary のキーに ValueTuple を使っているため、.NET Framework 4.7 以降が対象です。
var key = (x.id, x.date, x.koumokuNum, x.koumoku2Num, x.koumoku3Num); // 複合キーを ValueTuple で表現しています
if (!dict.TryGetValue(key, out var item))
{
dict.Add(key, item = new KirokuSelected
{
id = x.id,
date = x.date,
koumokuNum = x.koumokuNum,
koumoku2Num = x.koumoku2Num,
koumoku3Num = x.koumoku3Num, // ←koumoku3Num をキーにすべきかは疑問なので、ここは要確認。
kirokuNum1kiroku = "",
kirokuNum2kiroku = "",
kirokuNum3kiroku = "", // 記録がない場合に「""」にするか「null」にするかはお好みで。
});
KirokuSelectedLst.Add(item); // 「選択記録データのリスト」に追加する
}
switch (x.kirokuNum) // Koumoku2Numが変わるごとに記録データを作成します。
{
case "0": break; // 条件:記録番号が「1」「2」「3」3種類。「0」は区切り用なので無視します。
case "1": item.kirokuNum1kiroku = x.kiroku; break;
case "2": item.kirokuNum2kiroku = x.kiroku; break;
case "3": item.kirokuNum3kiroku = x.kiroku; break;
default: throw new IndexOutOfRangeException(nameof(KoumokuData.kirokuNum));
}
return item;
}).ToArray();
}
|