10

次の形式のテーブルがあります。

PID     ID       Label        Value
------------------------------------------
1       1        First Name    Jenna
1       2        DOB           10/12/1980

Jで始まる名とDOBの月が10であるすべてのPIDを取得する必要があります。

私のコードでは、C#のDataTableでこれらを取得してから、LINQを使用して必要な結果を取得しようとしました。これは単なる例です。これらのラベルは、ユーザーが定義するものであれば何でもかまいません。

LINQを使用すると、名がJで始まるすべてのPIDを取得できますが、DOBの値をキャストしようとするたびに、キャストが無効なエラーが発生します。Valueには任意のタイプの情報が含まれている可能性があるため、データベースの列タイプを変更できません。

これが私のコードの一部です。私はLINQを初めて使用しますが、それでもその周りを理解しようとしています。

var resultQuery = from r in query.AsEnumerable()
where (r.Field<string>("Label") == Label  &&
r.Field<DateTime>("Value").Month == 10)
select r.Field<int>("PID");
4

2 に答える 2

4

表の [値] 列のすべてのアイテムが に変換できるわけではないためDateTime、無効な変換で失敗します。DateTime値が a であることを最初に確認し、そうである場合にのみ、それを変換してプロパティを確認する句を追加でき.Monthます。

DateTime d;
var resultQuery = from r in query.AsEnumerable()
                  where (r.Field<string>("Label") == Label &&
                      DateTime.TryParse(r.Field<string>("Value"), out d) && 
                      d.Month == 10)
                  select r.Field<int>("PID");

読みやすさを潜在的に改善するために、これを別のメソッドに抽出することもできます。

var resultQuery = from r in query.AsEnumerable()
                  let d = TryGetDate(r.Field<string>("Value"))
                  where (r.Field<string>("Label") == Label &&
                      d != null && 
                      d.Month == 10)
                  select r.Field<int>("PID");

private DateTime? TryGetDate(string value)
{
    DateTime d;
    return DateTime.TryParse(value, out d) ? d : default(DateTime?);
}
于 2012-10-19T18:21:45.713 に答える
2

あまり効率的ではないメモリ内でフィルタリングすることになります。

最初にデータを選択します

var data= from r in query.AsEnumerable();

次に、データをフィルタリングします

var filtered = from item in data
               where item.Label == "Label"
               && Convert.ToDateTime(item.DOB).Month == 10
               select item.PID;
于 2012-10-19T18:31:14.477 に答える