========================================================
作者: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
========================================================