2013-05-14 93 views
0

嗨,我有以下字段如何写这个LINQ查询

DAT_START 
GROUPBY 
TXT_LATITTUDE 
TXT_LONGITUDE 
INT_DIRECTION 
INT_CALL_DATA_TYPE 
LNG_DURATION 

而继一个DataTable的LINQ查询我使用

var data = (from r in dt.AsEnumerable() 
where ((r.Field<DateTime>("DAT_START").TimeOfDay.Hours < 20) && (r.Field<DateTime>("DAT_START").TimeOfDay.Hours >= 4)) 
group r by new { CID = r["GroupBy"], CLatitude = r["TXT_LATITUDE"], CLongitude = r["TXT_LONGITUDE"],CDirection = r["INT_DIRECTION"], 
CCallType = r["INT_CALL_DATA_TYPE"],CDuration = r["LNG_DURATION"] } 
into groupedTable 
select new 
{ 
    CellID = groupedTable.Key.CID, 
    CallCount = groupedTable.Count(), 
    Longitude = groupedTable.Key.CLongitude, 
    Latitude = groupedTable.Key.CLatitude, 
    Direction = groupedTable.Key.CDirection, 
    CallType = groupedTable.Key.CCallType, 
    Duration = groupedTable.Key.CDuration 
}).OrderByDescending(s => s.CallCount); 

它给我造成这样

CellID = 4057,CallCount = 84,Longitude = "",Latitude = "",Direction = "Incoming",CallType = "Voice",Duration = 50 
CellID = 4057,CallCount = 8,Longitude = "",Latitude = "",Direction = "Outgoing",CallType = "Voice",Duration =97 
CellID = 4057,CallCount = 56,Longitude = "",Latitude = "",Direction = "Incoming",CallType ="SMS" ,Duration = 0 
CellID = 4057,CallCount = 41,Longitude = "",Latitude = "",Direction = "Outgoing",CallType = "SMS",Duration = 0 

现在我想要这样的结果

CellID = 4057, TotalCommCount = 204, TotalDuration = 147, INSMSCount = 56,OutSMSCount = 41, INVoiceCount = 84,OutVoiceCount = 8,InVoiceDuration =50,OutVoiceDuration = 47 

我该怎么做。我在这里被击晕..

+0

不知道,但你不能通过'CellID'进行进一步的分组,然后总结其他列吗? – Habib 2013-05-14 06:15:35

+0

您是否尝试过使用SQL!?它会简单得多,不管你如何使用DataTable,为什么要在代码中做这么混乱的工作? – IamStalker 2013-05-14 06:16:42

+0

@Habib我需要通过'Direction'和'CallType'获得所有'持续时间'以及'持续时间'组的总和。 – 2013-05-14 06:19:54

回答

6

看起来你现在正在分组太多,这就是为什么你会得到多行。我怀疑你想是这样的:

from r in dt.AsEnumerable() 
where r.Field<DateTime>("DAT_START").TimeOfDay.Hours < 20 && 
     r.Field<DateTime>("DAT_START").TimeOfDay.Hours >= 4 
group r r["GroupBy"] into g   
select new 
{ 
    CellID = g.Key, 
    TotalCommCount = g.Count(), 
    TotalDuration = g.Sum(r => r.Field<long>("LNG_DURATION")), 
    InSMSCount = g.Count(r => r.Field<string>("DIRECTION") == "Incoming" && 
           r.Field<string>("CALL_TYPE") == "SMS"), 
    OutSMSCount = g.Count(r => r.Field<string>("DIRECTION") == "Outgoing" && 
           r.Field<string>("CALL_TYPE") == "SMS"), 
    InVoiceCount = g.Count(r => r.Field<string>("DIRECTION") == "Incoming" && 
           r.Field<string>("CALL_TYPE") == "Voice"), 
    OutVoiceCount = g.Count(r => r.Field<string>("DIRECTION") == "Outgoing" && 
           r.Field<string>("CALL_TYPE") == "Voice"), 
    InVoiceDuration = g.Where(r => r.Field<string>("DIRECTION") == "Incoming" && 
           r.Field<string>("CALL_TYPE") == "Voice") 
         .Sum(r => r.Field<long>("DURATION")) 
    OutVoiceDuration = g.Where(r => r.Field<string>("DIRECTION") == "Outgoing" && 
            r.Field<string>("CALL_TYPE") == "Voice"), 
         .Sum(r => r.Field<long>("DURATION")) 
} into summary 
order by summary.TotalCommCount descending 
select summary; 
+0

感谢乔恩,它正在工作。我在数据表中遇到了一些问题。 – 2013-05-14 06:59:04

0

我建议你创建你的SQL数据库中的视图,你可以简单地聚合您需要什么,然后使用该视图中的Linq查询 - 这将执行速度快,它很容易写。

草图设计:

由于您的要求的描述是不完全清楚,我做了假设。通过使用“更新

CREATE VIEW [dbo].[vSumDurations] 
AS 
select c.CellId, j1.SumDuration1 as TotalDuration, 
     j2.SumDuration2 as GroupedDuration, j1.CallCount 
from (select distinct t.CID as CellId from [dbo].[YourTable] t) c 
left join (select t1.CID as CellId, sum(LNG_Duration) as SumDuration1, 
      count(*) as CallCount from [dbo].[YourTable] t1 
      Group By t1.CID) j1 
on c.CellId=j1.CellId   
left join (select t2.CID as CellId, sum(LNG_Duration) as SumDuration2 
      from [dbo].[YourTable] t2 
      Group by t2.CID, t2.Direction, t2.CallType) j2 
on c.CellId=j2.CellId 

(你知道你可以轻松地这个视图添加到您的*的.edmx: 创建SQL视图如(这只是为了显示这个想法,根据您的需要改变它)从数据库模型”中的实体图页面的上下文菜单,然后刻度线的视图vSumDurations‘会弹出对话框的表/视图’部分)。

这个准备您的Linq查询是后非常简单,因为一切都已经在视图中完成了。因此,代码如下:

var dc = this; // in LinqPad you can set your data context 
var data = (from d in dc.vSumDurations select d).OrderByDescending(s => s.CallCount); 
data.Dump(); 

注:的例子是由为LinqPad - 你需要在你的实际代码不同的数据上下文。 Linqpad不需要dc,但是如果您为了便利的原因而声明它更容易,因为在您的真实代码中必须提供它。