[.NET] EF LINQ 按时间对数据分类汇总
========================================================
作者:qiujuer
博客:blog.csdn.net/qiujuer
网站:www.qiujuer.net
开源库:Genius-Android
转载请注明出处:http://blog.csdn.net/qiujuer/article/details/41868331
========================================================
发现国内弄 Mvc 和 WebAPI 的人简直少的可怜啊;前段时间发了大量的 WebAPI 的相关博文看的人不多;可以说是无人问津。
在对数据的操作中,对一堆数据的分类汇总是比较常见的,特别是按照时间进行分类汇总。比如算出某一天,某一月的数据总量等等。而鉴于国内研究的人少所以遇到一些问题简直没法查询,其中就包括:
<ExceptionMessage> LINQ to Entities 不识别方法“System.String ToString(System.String)”,因此该方法无法转换为存储表达式。 </ExceptionMessage>
现在我有一堆存储在数据库中的数据;其数据简单格式如下:
public class DataModel { public int Id { get; set; } public string Data { get; set; } public DateTime Time { get; set; } }就只有一个数据,一个时间,一个标志字段。
方案一
方案二
var note2 = db.Notes // 先进行了时间字段变更为String字段,切只保留到天 .Select(n => new { Data = n.Data, Time = n.Time.ToString("yyyy-MM-dd") }) // 分类 .GroupBy(n => n.Time) // 返回汇总样式 .Select(n => new { Time = n.Key, Datas = n.ToList() }).ToList();方法似乎很正确,但是运行后:
<Error> <Message>出现错误。</Message> <ExceptionMessage> LINQ to Entities 不识别方法“System.String ToString(System.String)”,因此该方法无法转换为存储表达式。 </ExceptionMessage> <ExceptionType>System.NotSupportedException</ExceptionType> <StackTrace>...</StackTrace> </Error>这时就出现了这样的情况,是我们的思路错了?不是,思路完全正确。只是在 EF 中的 LINQ 不能识别 ToString 而已。
方案三
var note3 = db.Notes // 先进行了时间字段变更为String字段,切只保留到天 // 采用拼接的方式 .Select(n => new { Data = n.Data, Time = n.Time.Year + "-" + n.Time.Month + "-" + n.Time.Day }) // 分类 .GroupBy(n => n.Time) // 返回汇总样式 .Select(n => new { Time = n.Key, Datas = n.ToList() }).ToList();既然不能返回,那我们就来自己拼接;这种方式能够正确执行并返回正确数据。推荐!!!
方案四
// 先进行数据查询,返回数据 var datas = await db.Notes.ToListAsync(); // 然后在内存中使用 LINQ var note4 = datas.Select(n => new { Data = n.Data, Time = n.Time.ToString("yyyy-MM-dd") }) .GroupBy(n => n.Time) .Select(n => new { Time = n.Key, Datas = n.ToList() }).ToList();至于分类汇总的思路不变;只是把ToString 放到了独立的 LINQ 中使用而已;实践证明,这个是可行的方案。同样推荐!!!
区别是啥?
- 因为 方案三 基本上是把所有的工作放在了 SQL 上执行,这边只负责接收成果就OK 了!
- 而 方案四 则是获取数据是在 SQL 操作,但是数据的处理是放在服务器端内存中进行的!
其优劣性
- 如果你的 SQL 数据性能远远大于 你的服务器后台 配置,那么才有第三方案 是比较划算的。
- 如果你的 服务器的内存不错,分析也不错;能完全胜任其数据处理的话 第四方案 是你的不二选择。
实际使用
<ArrayOfNoteInfo xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/GeniusSpace.Controllers.Api"> <NoteInfo> <Changes> <SNote> <Content>似的撒旦</Content> <Time>2014-12-11</Time> </SNote> <SNote> <Content>sewrwfqf</Content> <Time>2014-12-11</Time> </SNote> <SNote> <Content>sgewhsdwqd</Content> <Time>2014-12-11</Time> </SNote> </Changes> <Time>2014-12-11</Time> </NoteInfo> <NoteInfo> <Changes> <SNote> <Content>asgafasgre</Content> <Time>2014-12-10</Time> </SNote> <SNote> <Content>dgwetwet</Content> <Time>2014-12-10</Time> </SNote> </Changes> <Time>2014-12-10</Time> </NoteInfo> <NoteInfo> <Changes> <SNote> <Content>rwqyhtrjhdf</Content> <Time>2014-12-09</Time> </SNote> </Changes> <Time>2014-12-09</Time> </NoteInfo> </ArrayOfNoteInfo>这是我这边使用的情况,当然其参数与上面的参数不对;但是其分类汇总是完成了的。
采用的是 第三方案 ,其 SQL 语句如下:
SELECT [Project2].[C2] AS [C1], [Project2].[C1] AS [C2], [Project2].[C4] AS [C3], [Project2].[Content] AS [Content], [Project2].[C3] AS [C4] FROM ( SELECT [Distinct1].[C1] AS [C1], 1 AS [C2], [Extent2].[Content] AS [Content], CASE WHEN ([Extent2].[Content] IS NULL) THEN CAST(NULL AS varchar(1)) ELSE CASE WHEN (DATEPART (year, [Extent2].[Published]) IS NULL) THEN N'' ELSE CAST( DATEPART (year, [Extent2].[Published]) AS nvarchar(max)) END + N'-' + CASE WHEN (DATEPART (month, [Extent2].[Published]) IS NULL) THEN N'' ELSE CAST( DATEPART (month, [Extent2].[Published]) AS nvarchar(max)) END + N'-' + CASE WHEN (DATEPART (day, [Extent2].[Published]) IS NULL) THEN N'' ELSE CAST( DATEPART (day, [Extent2].[Published]) AS nvarchar(max)) END END AS [C3], CASE WHEN ([Extent2].[Content] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C4] FROM (SELECT DISTINCT CASE WHEN (DATEPART (year, [Extent1].[Published]) IS NULL) THEN N'' ELSE CAST( DATEPART (year, [Extent1].[Published]) AS nvarchar(max)) END + N'-' + CASE WHEN (DATEPART (month, [Extent1].[Published]) IS NULL) THEN N'' ELSE CAST( DATEPART (month, [Extent1].[Published]) AS nvarchar(max)) END + N'-' + CASE WHEN (DATEPART (day, [Extent1].[Published]) IS NULL) THEN N'' ELSE CAST( DATEPART (day, [Extent1].[Published]) AS nvarchar(max)) END AS [C1] FROM [dbo].[Notes] AS [Extent1] ) AS [Distinct1] LEFT OUTER JOIN [dbo].[Notes] AS [Extent2] ON ([Distinct1].[C1] = (CASE WHEN (DATEPART (year, [Extent2].[Published]) IS NULL) THEN N'' ELSE CAST( DATEPART (year, [Extent2].[Published]) AS nvarchar(max)) END + N'-' + CASE WHEN (DATEPART (month, [Extent2].[Published]) IS NULL) THEN N'' ELSE CAST( DATEPART (month, [Extent2].[Published]) AS nvarchar(max)) END + N'-' + CASE WHEN (DATEPART (day, [Extent2].[Published]) IS NULL) THEN N'' ELSE CAST( DATEPART (day, [Extent2].[Published]) AS nvarchar(max)) END)) OR (([Distinct1].[C1] IS NULL) AND (CASE WHEN (DATEPART (year, [Extent2].[Published]) IS NULL) THEN N'' ELSE CAST( DATEPART (year, [Extent2].[Published]) AS nvarchar(max)) END + N'-' + CASE WHEN (DATEPART (month, [Extent2].[Published]) IS NULL) THEN N'' ELSE CAST( DATEPART (month, [Extent2].[Published]) AS nvarchar(max)) END + N'-' + CASE WHEN (DATEPART (day, [Extent2].[Published]) IS NULL) THEN N'' ELSE CAST( DATEPART (day, [Extent2].[Published]) AS nvarchar(max)) END IS NULL)) ) AS [Project2] ORDER BY [Project2].[C1] ASC, [Project2].[C4] ASC从语句可以看出,其分类汇总,以及查询全部都是在SQL端完成。
作者:qiujuer
博客:blog.csdn.net/qiujuer
网站:www.qiujuer.net
开源库:Genius-Android
转载请注明出处:http://blog.csdn.net/qiujuer/article/details/41868331
========================================================
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。