2011-10-18 45 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