2014-12-03 86 views
0

以獲得最新的項目我有以下相關的表:LINQ(和SQL)的獨特性質

  • 機[關鍵]
  • 樣品
  • 實驗
  • DateCompleted
  • ...一些測試值在其上予執行一些計算

STRUCT ure

Machine - Sample - Experiment - Completed - ... 
m1  - s1  - e1   - <date> - ... 
m1  - s1  - e2   - <date> - ... 
m1  - s2  - e1   - <date> - ... 
.... 
m2  - s3  - e1   - <date> - ... 
.... 

在每臺機器上,可以對單個樣品進行多個實驗。

我的目標是識別每臺機器的5最新-distinct-樣品,並得到所有相關的條目(整行,包括每個該樣品所有實驗)。

我似乎無法找到我一次通過組通過機降DateCompleted下一步和秩序。

我猜某種「DistinctBy(X => x.Sample)」是必要的,但並沒有設法去解決它。

例子:

Machine - Sample - Experiment 
m1 - s1 - e1 * 
m1 - s1 - e2 * 
m1 - s2 - e1 * 
m1 - s2 - e2 * 
m1 - s3 - e1 * 
m1 - s4 - e1 * 
m1 - s4 - e2 * 
m1 - s5 - e1 * 
m1 - s6 - e1 
m1 - s6 - e2 
... 

我需要所有的行標有「*」作爲我的查詢的輸出(通過說降日期已經訂購) - 對每一臺機器左右。

我很努力地寫這個SQL語句。 如果你知道你會如何在SQL中編寫它,發佈它,我可能會從中得到一些東西。

編輯:

好吧,我試圖從下往上再一次去,我的第一次嘗試是確定最新的5個樣品。

下面的查詢,使用固定的值,作品

var samples = (from c in db.Experiments 
      where c.Machine == "m1" 
      orderby c.Completed descending 
      select c.Sample).ToList().Distinct().Take(5) 

我需要添加 「ToList()」,因爲鮮明的()弄亂它並非如此。

現在,當我進入包括另一個查詢,在這裏我想每每臺機器的結果這一點 - 它不工作 - 它不會被降完成日期訂購,但保持「隨機」的順序。

這是爲什麼?

var last5samples = (from t in db.Experiments 
        group t by new { t.Machine } into g 
        select new 
        { 
         Machine = g.Key.Machine, 
         Samples = (from c in db.Experiments 
            where c.Machine == g.Key.Machine 
            orderby c.Completed descending 
            select c.Sample).ToList().Distinct().Take(5) 
        }); 

編輯2:

嘗試另一種方法,以爭取確實是我需要 - 包含最後5個樣本中的所有行。 這很慢,但「有效」,除了orderby降序不工作。

我用「IN」的方法去,但後來看到了與LINQ我需要反邏輯,這就是我想出了:

var last5samples = from t in db.Experiments 
        where (from c in db.Experiments 
          where c.Machine == t.Machine 
          orderby c.Completed descending 
          select c.Sample).ToList().Distinct().Take(5) 
        .Contains(t.Sample) 
        select t; 

我的主要問題是現在如何按預期順序下降工作。

我不明白它爲什麼在它是獨奏查詢時,以及子查詢時不起作用。

+0

您需要包含morelinq for distinctBy。你可以參考這個線程:http://stackoverflow.com/questions/998066/linq-distinct-values – 2014-12-03 11:12:33

+0

與SQL,你需要使用窗口函數 – hazimdikenli 2014-12-03 11:19:49

+0

@IsThatSo,在這裏(http://stackoverflow.com/questions/ 2537823/lin-class-by-class-by-by-linq)Jon Skeet提到它僅適用於類,它不適用於LINQ to SQL。 – dbu 2014-12-03 11:23:12

回答

0

LINQ沒有DistinctBy功能,但幸運的是有一個名爲morelinq的庫允許您這樣做。

var results = query.DistinctBy(x => x.Sample).ToList(); 
0
using System; 
using System.Linq; 
using System.Collections.Generic; 


public class Program 
{ 
    public void Main() 
    { 

     var list = new List<Test>(); 
     list.Add(new Test { Machine = "m1", Sample = "s1", Experiment = "e1", DateCompleted = DateTime.Now.AddDays(-2) }); 
     list.Add(new Test { Machine = "m1", Sample = "s1", Experiment = "e1", DateCompleted = DateTime.Now.AddDays(-1) }); 
     list.Add(new Test { Machine = "m1", Sample = "s1", Experiment = "e1", DateCompleted = DateTime.Now }); 
     list.Add(new Test { Machine = "m2", Sample = "s1", Experiment = "e1", DateCompleted = DateTime.Now.AddDays(-2) }); 
     list.Add(new Test { Machine = "m2", Sample = "s1", Experiment = "e1", DateCompleted = DateTime.Now.AddDays(-1) }); 
     list.Add(new Test { Machine = "m2", Sample = "s1", Experiment = "e1", DateCompleted = DateTime.Now.AddHours(-1) }); 

     var q = from s in list 
       group s by new { s.Machine, s.Sample } 
        into gs 
        select new 
        { 
         Machine = gs.Key.Machine 
         , 
         Sample = gs.Key.Sample 
         , 
         Rows = gs.OrderByDescending(f => f.DateCompleted).Take(5) 
        }; 
     foreach (var p in q.ToList()) 
     { 
      Console.WriteLine("{0} {1} {2}", p.Machine, p.Sample, p.Rows.Count()); 
     } 
    } 
} 



public class Test 
{ 
    public string Machine { get; set; } 
    public string Sample { get; set; } 
    public string Experiment { get; set; } 
    public DateTime DateCompleted { get; set; } 
} 
+0

我不確定您是否需要通過機器+實驗進行分組,或者只是通過實驗進行分組。 – hazimdikenli 2014-12-03 11:40:20

+0

小提琴在這裏:https://dotnetfiddle.net/R9cir7 – hazimdikenli 2014-12-03 11:46:32

+0

我不認爲這就是我需要的。 查看原始文章中添加的示例。 對於每臺機器,我需要屬於最新5個樣本的所有行。 – dbu 2014-12-03 12:20:20

0

好了,這是我如何解決它。

在嘗試了我能找到的所有東西之後,並不理解爲什麼distinct + orderby在一種情況下(「獨奏」查詢)而不是另一種(子查詢),我繼續按照「我的方式」來做。它的工作速度還不夠快(比我最新編寫的LINQ,在編輯2中更快)。

這就是:

  1. 我得到的所有不同的機器
  2. 對於每一個機器,我取了其最新的5個樣品
  3. 對於每一個機器,我獲得一個包含最新的5個樣品

    foreach (var m in machines) 
    { 
    
    var last5Samples = (from t in db.Experiments 
           where t.Machine = m.Machine 
           orderby t.Completed descending 
           select t.Sample).ToList().Distinct().Take(5); 
    
    var expsForLast5Samples = from t in db.Experiments 
             where last5Samples.Contains(t.Sample) 
             select t; 
    }