6

同等の Linq To Objects クエリを作成するにはどうすればよいですか?

SELECT MIN(CASE WHEN p.type = "In" THEN p.PunchTime ELSE NULL END ) AS EarliestIn,
       MAX(CASE WHEN p.type = "Out" THEN p.PunchTime ELSE NULL END ) AS LatestOUt
FROM Punches p
4

3 に答える 3

4

minとmaxの両方(およびそこにスローしたい他の集計)を生成する単一の列挙。これはvb.netでははるかに簡単です。

私はこれが空のケースを処理しないことを知っています。追加するのはとても簡単です。

    List<int> myInts = new List<int>() { 1, 4, 2, 0, 3 };
    var y = myInts.Aggregate(
        new { Min = int.MaxValue, Max = int.MinValue },
        (a, i) =>
        new
        {
           Min = (i < a.Min) ? i : a.Min,
           Max = (a.Max < i) ? i : a.Max
        });
    Console.WriteLine("{0} {1}", y.Min, y.Max);
于 2008-09-30T20:55:41.800 に答える
2

通常の LINQ to Objects で複数の集計を効率的に選択することはできません。もちろん、複数のクエリを実行できますが、データ ソースによっては効率が悪い場合があります。

私は「Push LINQ」と呼んでいるこれに対処するフレームワークを持っています。これは単なる趣味です (私と Marc Gravell にとって) ですが、かなりうまく機能すると信じています。これはMiscUtilの一部として利用でき、それについては私のブログ投稿で読むことができます。

少し奇妙に見えます-結果をどこに送るかを「先物」として定義し、クエリを介してデータをプッシュしてから結果を取得するためです-しかし、頭が丸くなったら問題ありません。あなたがそれをどのように使いこなしているかを知りたいです - もしあなたがそれを使っているなら、skeet@pobox.com まで私にメールしてください。

于 2008-09-30T19:59:40.467 に答える
0

LINQ-to-Objects を使用して複数の集計を行うことは可能ですが、少し醜いです。

var times = punches.Aggregate(
    new { EarliestIn = default(DateTime?), LatestOut = default(DateTime?) },
    (agg, p) => new {
        EarliestIn = Min(
            agg.EarliestIn,
            p.type == "In" ? (DateTime?)p.PunchTime : default(DateTime?)),
        LatestOut = Max(
            agg.LatestOut,
            p.type == "Out" ? (DateTime?)p.PunchTime : default(DateTime?)) 
    }
);

これらは標準で利用できないため、DateTime の Min および Max 関数も必要になります。

public static DateTime? Max(DateTime? d1, DateTime? d2)
{
    if (!d1.HasValue)
        return d2;
    if (!d2.HasValue)
        return d1;
    return d1.Value > d2.Value ? d1 : d2;
}
public static DateTime? Min(DateTime? d1, DateTime? d2)
{
    if (!d1.HasValue)
        return d2;
    if (!d2.HasValue)
        return d1;
    return d1.Value < d2.Value ? d1 : d2;
}
于 2010-01-19T15:55:33.960 に答える