服務(wù)器環(huán)境如下:
系統(tǒng): Ubuntu 10.10
Web服務(wù)器:Jexus/4.2.3 Linux
Mono版本: Mono 2.10.1
代碼如下:
1 using (BizDataContext BDC = new BizDataContext())
2 {
3 int colID = ColumnInfo.ID;
4 var list = from o in BDC.Article where o.ColID == ColumnInfo.ID orderby o.ID descending select new { ArticleID = o.ID, Title = o.Title, ColID = o.ColID, CreateAt = o.CreateAt };
5 pageSplit1.RecordCount = list.Count();
6 rptList.DataSource = list.Skip((pageSplit1.PageIndex - 1) * pageSplit1.PageSize).Take(pageSplit1.PageSize);
7 rptList.DataBind();
8 }
這個代碼在IIS下運行一切正常,然后在Mono下就出錯了,報出如下的錯誤。
Description: HTTP 500. Error processing request.
經(jīng)過一番測試,貌似是where條件和new的匿名對象不能同時存在就會報這個錯。于是把linq查詢的代碼改成如下:
var list = from o in BDC.Article where o.ColID == colID orderby o.ID descending select o;
繼續(xù)運行,繼續(xù)報錯。
Description: HTTP 500. Error processing request.
這個錯誤貌似是sql查詢引起的,于是打印出linq翻譯出的sql語句,如下:
1 SELECT * FROM ( SELECT [ArticleID], [SiteID], [AdminID], [ColID], [Title], [SubTitle], [CreateAt], [Click], [Reply], [Description], [Content], [Cover], [Type], [AlbumID] , ROW_NUMBER() OVER(ORDER BY [ArticleID], [SiteID], [AdminID], [ColID], [Title], [SubTitle], [CreateAt], [Click], [Reply], [Description], [Content], [Cover], [Type], [AlbumID] ) AS [__ROW_NUMBER] FROM [con_Article] WHERE ([ColID] = ) AS [t0] WHERE [__ROW_NUMBER] BETWEEN 0+1 AND 0+20 ORDER BY [__ROW_NUMBER]
注意加粗的部分,居然是 ([ColID] = ) 。等于的值呢?居然變成空白了。 而且Mono的linq2sql與.NET的linq2sql翻譯機制有點區(qū)別,.NET轉(zhuǎn)換過來的sql如下:
SELECT [t1].[ArticleID] AS [ID], [t1].[SiteID], [t1].[AdminID], [t1].[ColID], [t1].[Title], [t1].[SubTitle], [t1].[CreateAt], [t1].[Click], [t1].[Reply], [t1].[Description], [t1].[Content], [t1].[Cover], [t1].[Type], [t1].[AlbumID] FROM ( SELECT ROW_NUMBER() OVER (ORDER BY [t0].[ArticleID] DESC) AS [ROW_NUMBER], [t0].[ArticleID], [t0].[SiteID], [t0].[AdminID], [t0].[ColID], [t0].[Title], [t0].[SubTitle], [t0].[CreateAt], [t0].[Click], [t0].[Reply], [t0].[Description], [t0].[Content], [t0].[Cover], [t0].[Type], [t0].[AlbumID] FROM [con_Article] AS [t0] WHERE [t0].[ColID] = @p0 ) AS [t1] WHERE [t1].[ROW_NUMBER] BETWEEN @p1 + 1 AND @p1 + @p2 ORDER BY [t1].[ROW_NUMBER]
他們最大的區(qū)別就是Mono查詢的內(nèi)容會多上一個字段 [__ROW_NUMBER],ps: 多出來的這個字段在某些環(huán)境下也會造成Mono和IIS的操作方法不一致,比如說 DataContext.Translate 方法 。
進(jìn)一步測試,如果去掉Skip和Take方法,則生成的sql語句就是正確的了,看來是where條件和take、Skip方法是存在沖突的。(ps: 經(jīng)測試,單獨使用Skip和Take方法生成的sql與不加這2個方法是一樣的,即Skip和Take如果單獨使用是無效的).
總結(jié)一下,發(fā)現(xiàn)了2點BUG
1、where 查詢和匿名函數(shù)不能并存
2、where 查詢和分頁方法(Skip、Take)不能并存
在這個bug得到解決之前,我的列表頁看來是不能用Linq做了。
ps: 如果有興趣研究.NET for Mono 的,我可以提供相關(guān)的空間測試環(huán)境,有興趣可加QQ 21979631。
如對本文有疑問,請?zhí)峤坏浇涣髡搲?,廣大熱心網(wǎng)友會為你解答??! 點擊進(jìn)入論壇