2011-10-18 80 views
0

我有一個測試數據庫,它記錄了商店登錄商店門戶時的數據以及它保持登錄的時間。Linq - 如何獲得最小值,如果值= 0,獲得下一個值

例子: (只用於可視化的目的 - 不是實際的數據庫)

Stores 
Id Description  Address   City 
1 Candy shop  43 Oxford Str. London 
2 Icecream shop 45 Side Lane Huddersfield 

Connections 
Id Store_Ref Start     End 
1   2 2011-02-11 09:12:34.123 2011-02-11 09:12:34.123 
2   2 2011-02-11 09:12:36.123 2011-02-11 09:14:58.125 
3   1 2011-02-14 08:42:10.855 2011-02-14 08:42:10.855 
4   1 2011-02-14 08:42:12.345 2011-02-14 08:50:45.987 
5   1 2011-02-15 08:35:19.345 2011-02-15 08:38:20.123 
6   2 2011-02-19 09:08:55.555 2011-02-19 09:12:46.789 

我需要從數據庫中獲取的各種數據。我已經獲得了最大和平均的連接時間。 (所以可能非常不言而喻......)我還需要獲得關於哪個連接持續時間最少的信息。我當然立即想到了Linq的Min()函數,但正如你所看到的,數據庫還包括立即開始和結束的連接。因此,該數據對於數據分析實際上並不「有效」。

所以我的問題是如何獲得最小值,但如果值= 0,獲得最低的下一個值。

我的LINQ查詢到目前爲止(它實現MIN()函數):

var min = from connections in Connections 
      join stores in Stores 
      on connections.Store_Ref equals stores.Id 
      group connections 
      by stores.Description into groupedStores 
      select new 
      { 
      Store_Description = groupedStores.Key, 
      Connection_Duration = groupedStores.Min(connections => 
              (SqlMethods.DateDiffSecond(connections.Start, connections.End))) 
      }; 

我知道,它可能通過多種查詢和/或聲明,以獲得有效的值,雖然,但我在想,如果只需要一個查詢就可以完成所有工作,因爲我的程序希望返回linq查詢,並且我的偏好是儘可能保持程序「輕」。

如果您必須非常好/簡單的方法才能這樣做,請分享它。你的貢獻非常感謝! :)

回答

0
var min = from connections in Connections.Where(connections => (SqlMethods.DateDiffSecond(connections.Start, connections.End) > 0) 
      join stores in Stores 
      on connections.Store_Ref equals stores.Id 
      group connections 
      by stores.Description into groupedStores 
      select new 
      { 
      Store_Description = groupedStores.Key, 
      Connection_Duration = groupedStores.Min(connections => 
              (SqlMethods.DateDiffSecond(connections.Start, connections.End))) 
      }; 

試試這個,通過過濾「0」值你會得到正確的結果,至少這是我的教導。

+1

它的工作原理!我認爲這會變得更加困難,但它變得非常簡單......我甚至沒有想到這一點。 (我對lambda表達式沒有太多的經驗)但無論如何,謝謝@Frederiek!非常感謝! – doc92

+0

那麼這是最簡單的解決方案。你也可以把聲明中的哪個部分放在聲明中,這會使聲明更加複雜,我的方式是說「只搜索valids」 – Frederiek

1

如果你選擇新的,let語句前添加,對於連接如持續時間的東西,如:

let duration = SqlMethods.DateDiffSecond(connections.Start, connections.End) 

,然後添加一個where子句

where duration != 0 
+0

這一個也可以工作:)我甚至不知道還有一個let clausule大聲笑)。然而,我想我會和@ Frederiek的解決方案(它有更少的代碼)一起去,但是感謝你的想法和輸入! – doc92

+0

使用let子句,您將獲得僅計算一次該值的優勢。如果多次使用SqlMethods.DateDiffSecond(...),它將每次執行該函數。所以'讓'可以節省你一些時間:) –

0

包括where條款在計算最小值之前。

groupedStores.Where(conn => SqlMethods.DateDiffSecond(conn.Start, conn.End) > 0) 
    .Min(conn => (SqlMethods.DateDiffSecond(conn.Start, conn.End)) 
+0

我試過這一個,但我似乎得到一個錯誤(不能隱式轉換類型'int?'爲'布爾')? – doc92