[英]How to write this LINQ Query
嗨,我有一个包含以下字段的数据表
DAT_START
GROUPBY
TXT_LATITTUDE
TXT_LONGITUDE
INT_DIRECTION
INT_CALL_DATA_TYPE
LNG_DURATION
以下是我正在使用的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
我怎样才能做到这一点。 我被打到这里了。
看来您目前分组过多,这就是为什么要获得多行的原因。 我怀疑您想要这样的东西:
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;
我建议您在SQL数据库中创建一个视图,您可以在其中简单地聚合所需的内容,然后在Linq查询中使用该视图-这样可以快速执行并且易于编写。
设计草图:
由于您对需求的描述并不十分清楚,因此我做了一些假设。 创建一个SQL视图,例如(只是为了显示想法,根据您的需要进行更改):
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
(您知道您可以通过使用实体图页面的上下文菜单中的“从数据库更新模型”,然后在对话框的“表/视图”部分中标记视图vSumDurations,轻松地将此视图添加到* .EDMX中。弹出。)
准备好之后,您的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
,但是出于方便的原因声明它会更容易,因为您必须在实际代码中提供它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.