CSVファイルがあり、各行の各要素を準備して検証し、有効なデータを持つクラスのコレクションを作成する必要があります。
つまり、CSVファイルは次のようになります。
EmpID,FirstName,LastName,Salary
1,James,Help,100000
2,Jane,Scott,1000
3,Mary,Fraze,10000
クラスは次のようになります。
public class Employees
{
public int EmpID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Salary { get; set; }
public string ErrorReason { get; set; }
}
各フィールドに必要な検証は次のとおりです。
EmpID:
FirstName(LastNameと同じ検証):
給料:
これを達成するために、これが私のアプローチです:
だから、私の質問は、これが正しいアプローチなのか、それともクラスのプロパティを検証する他のより良い/よりクリーンな方法があるのかということです。
データを入力してエラーをキャプチャする必要がある場合、私はおそらく次のようなことをするでしょう:
public class Employee
{
public int EmpID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Salary { get; set; }
}
public class ErrorEmployee : Employee
{
public string[] ErrorReason { get; set; }
}
エラーメッセージで通常のEmployee(単数形、それらのコレクションには複数形を使用)オブジェクトを汚染したくありません。上記のメモのように、FluentValidationライブラリをチェックして検証を確認し、最初に見つかったエラーだけでなく、エラーのリストをキャプチャします。
これは非常に単純な問題なので、これで間違ってしまうことはほとんどありません。あなたのアプローチはうまく見えます。
私が悪いことに気づいたのは、行ごとにDBをクエリしているという事実だけです。すべてのIDを使用してDBを1回だけクエリした方がよいでしょう。ただし、100行のみが可能であると仮定すると、これは問題になりません。しかし、私は少なくともコメントを書くでしょう、これは将来的に問題になるかもしれません。
3つのクラス
string[]
CSVLine:
{ public int LineNumber {get; set;} public string EmpID { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string Salary { get; set; } }
有効でない場合は、CSV行と検証エラーを拒否ファイルに記録できます。すべての属性を検証するか、すぐに失敗して最初のエラーで停止することができます。あなた次第。また、CSVLine内の名前付きフィールドが不要で、必要に応じて配列要素をバリデーターに渡すだけの場合は、CSVをstring []のような一般的な構造にする機会があります。配列の要素数(この場合は4)も検証できるため、配列の方が適している場合があります。
バリデーターをインターフェースにして、さまざまなタイプのバリデーターを作成することもできます。または、これが処理する唯一のファイルである場合は、クラスを1つだけ持つことができます。
リストされていない追加の合併症がない限り、それはかなり簡単です。これと同じくらい簡単なこと(疑似コード)が行います:
var customers = File.ReadAllLines("...")
.AsParallel()
.Select(l => l.Split(new char[] { ',' }))
.Where(s => Tuple.Create(
validateId(s[0]),
validateFirstName(s[1]),
validateLastName(s[2]),
validateSalary(s[3])))
.Select(t => new Customer(t.Item1, t.Item2, t.Item3, t.Item4));
ここでの唯一のニュアンスは、validateXYZが正しいタイプも検証して返すということです。
「ErrorReason」に関する限り、不良データを入力してから、不良データの理由を考えるのは悪い考えのようです。
数百万行が数秒で完了するファイルに対して、この正確な方法を使用して、これよりも複雑なクエリを記述しました。それよりも多くのデータがある場合は、実行する作業が増える可能性があります。
(ところで:これらのタイプの問題では、linqpadがあなたの友達です)。