2008-09-30 23 views
6

Eşdeğer Linq To Objects sorgusunu nasıl oluştururum?LINQ sorgusu çoklu topaklarla

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 

cevap

2

Vanilya LINQ'da Nesneler için birden çok kümeyi verimli bir şekilde seçemezsiniz. Elbette birden çok sorgu gerçekleştirebilirsiniz, ancak veri kaynağınıza bağlı olarak verimsiz olabilir.

ben "LINQ aktar" dediğiniz bu şekilde başa çıkabilen bir çerçeveye sahip - bu sadece (benim ve Marc Gravell için) bir hobi ama biz oldukça iyi çalışıyor inanıyoruz. MiscUtil'un bir parçası olarak kullanılabilir ve bunu my blog post on it'da okuyabilirsiniz.

Biraz garip görünüyor - çünkü sonuçların "gelecek" olarak nereye gitmesini istediğinizi tanımlarsınız, sonra verileri sorguya aktarır, sonra sonuçları alırsınız - ancak başınızı bir kez döndürdüğünüzde, bu iyi olur. Bununla nasıl baş edeceğinizi duymak isterim - eğer kullanırsanız, lütfen beni [email protected] adresine postalayın. min ve max (ve diğer agrega sen orada atmak istiyorum) hem verimli

+0

Teşekkür Jon. Linq ile ilgili en zor kısımlardan biri, ne yapabileceğinizi ve yapamayacağınızı anlamaya çalışmaktır. Standart metodolojiyle biraz daha rahat edersem kesinlikle Push tekniğinize bir göz atacağım. –

4

Tek numaralandırma. Bu, vb.net'de çok daha kolay.

Bunun boş durumun üstesinden gelmediğini biliyorum. Eklemek çok kolay.

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); 
+0

Bu biraz manuel ama benim için yeterince iyi. Linq'u ne zaman kırdığın, nasıl bir foreach görüntüsü için sadece sözdizimsel kısayollara dönüştüğün komiktir. –

+0

Ironik o zaman, öyle değil mi? foreach sadece sözdizimsel bir kısayol. –

+0

Downvoter, yorum yapmak ister misiniz? –

0

LINQ Nesneler ile birden agrega yapmak mümkündür, ama biraz çirkin. bu mevcut standart olmadığından

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?)) 
    } 
); 

Ayrıca DateTime Min ve Max işlevlerini gerekir.

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; 
}