請教各位大大
我寫了以下lambda搜尋式LastOrDefault(),改寫了各式各樣的方式,一直報錯。
int Revision = db.PaperFiles.Where(p => p.PaperId == PaperId && p.MemberId == MemberId && p.SubmittedType == submittedType && p.Stage == 2).LastOrDefault().Revision;
VS Error Message 使用者程式碼末處理NotSupportedException
'System.NotSupportedException' 類型的例外狀況發生於 EntityFramework.SqlServer.dll,但使用者程式碼未加以處理
其他資訊: LINQ to Entities 無法辨識方法 'Submission1.Areas.Users.Models.PaperFile LastOrDefault[PaperFile](System.Linq.IQueryable`1[Submission1.Areas.Users.Models.PaperFile])' 方法,而且這個方法無法轉譯成存放區運算式。
最後測試碼發現竟然是因為LastOrDefault()的問題,改寫FirstOrDefault()就過了,實在不懂為什麼會這樣,上來請教一下各位大師~
int Revision = db.PaperFiles.Where(p => p.PaperId == PaperId && p.MemberId == MemberId && p.SubmittedType == submittedType && p.Stage == 2).OrderByDescending(d => d.UploadDate).Select(f => f.Revision).FirstOrDefault();
謝謝指教
你上面和下面寫的不一樣啊 XD
一個是
LastOrDefault().Revision;
一個是
FirstOrDefault();
小魚大師,應該說我寫LastOrDefault()都出現Error(試了多種LastOrDefault()的寫法),但改成FirstOrDefault()就沒有發生Error了。但不知道為什麼用LastOrDefault()就會Error
我試過 LastOrDefault 本身是沒有問題的,
你確定你把LastOrDefault後面的 Revision
拿掉不能用嗎?
魚大,我又測試了一次,我很確定喔,執行結果如圖所示
執行程式碼如下
int Revision = db.PaperFiles.Where(p => p.PaperId == PaperId && p.MemberId == MemberId && p.SubmittedType == submittedType && p.Stage == 2).Select(f => f.Revision).LastOrDefault();
//int Revision = db.PaperFiles.Where(p => p.PaperId == PaperId && p.MemberId == MemberId && p.SubmittedType == submittedType && p.Stage == 2).OrderByDescending(d => d.UploadDate).Select(f => f.Revision).FirstOrDefault();
實在搞不懂為什麼FirstOrDefault就可以,LastOrDefault就Error
好像也有人遇到 這個問題
不過說真的SQL好像也沒有在取Last的,
都是從First開始...
既然日期由大往小排(DESC)取最後一個不能用
那跟從小往大排(ASC)取第一個,不是一樣的意思?
int Revision =
db.PaperFiles
.Where(p =>
p.PaperId == PaperId &&
p.MemberId == MemberId &&
p.SubmittedType == submittedType &&
p.Stage == 2)
.OrderBy(d => d.UploadDate)
.Select(f => f.Revision)
.FirstOrDefault();
(我還是習慣縮排一下,才看的懂階層關係)
結果是一樣的,
但奇檬子不一樣啊
兩段程式碼還是不一樣阿,FirstOrDefault的有OrderByDescending。
另外:https://stackoverflow.com/questions/7293639/linq-to-entities-does-not-recognize-the-method-last-really
主要是TSQL語法有Top但是沒有Last,不過其他家Provider有可能支援Last/LastOrDefault。
說到這個,
如果你轉成List再LastOrDefault可以嗎?
我之前測試是用List去做LastOrDefault的...
Linq to Entities轉成List時會Materialize,也就是產生SQL並查詢,然後再把查詢結果轉成List。之後呼叫LastOrDefault就跟SQL沒關係了。
回覆各位大大:
japhenchen意思是一樣的我知道,一開始直覺直接用LastOrDefault,結果無法執行,改成FirstOrDefault,只是把問題提出來,如果以後想用LastOrDefault就不會遇到同樣問題了~
小魚fillano大大,測試轉成List再LastOrDefault這樣就可以用了,感謝解答~
然後更正japhenchen大的說明,我要取日期最大的,所以應該是:
既然從小往大排(ASC)取最後一個不能用
那跟日期由大往小排(DESC)取第一個,不是一樣的意思?
.ToList() 是把所有的SQL查詢結果都傳回本地做成collection,再取Last,First..資料少沒什麼差別,資料多.........天知道會發生什麼事?
還是建議用LINQ的TAKE(n)在SQL端就處理好(跟SELECT TOP n等效)
int Revision =
db.PaperFiles
.Where(p => p.PaperId == PaperId &&
p.MemberId == MemberId &&
p.SubmittedType == submittedType
&& p.Stage == 2)
.OrderByDescding(od=>od.UploadDate)
.Take(1).Revision;
會以 SELECT TOP 1 * FROM PaperFiles WHERE ...... ORDER BY UploadDate DESC 執行
那如果是之前討論的寫法
int Revision = db.PaperFiles.Where(......).OrderBy(d => d.UploadDate).ToList().LastOnDefault();
則是 SELECT * FROM .... ORDER BY ..... ,有幾筆傳幾筆,只有三筆就傳三筆,有30萬筆也會照樣造句....你不在意網路流量跟本地記憶體被GC丟棄的資料量嗎?
了解,又上了一課,感謝japhenchen大師指導