服务器环境如下:
系统: Ubuntu 10.10
Web服务器: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.
经过一番测试,貌似是where条件和new的匿名对象不能同时存在就会报这个错。于是把linq查询的代码改成如下:
var list = from o in BDC.Article where o.ColID == colID orderby o.ID descending select o;
继续运行,继续报错。
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翻译机制有点区别,.NET转换过来的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]
他们最大的区别就是Mono查询的内容会多上一个字段 [__ROW_NUMBER],ps: 多出来的这个字段在某些环境下也会造成Mono和IIS的操作方法不一致,比如说 DataContext.Translate 方法 。
进一步测试,如果去掉Skip和Take方法,则生成的sql语句就是正确的了,看来是where条件和take、Skip方法是存在冲突的。(ps: 经测试,单独使用Skip和Take方法生成的sql与不加这2个方法是一样的,即Skip和Take如果单独使用是无效的).
总结一下,发现了2点BUG
1、where 查询和匿名函数不能并存
2、where 查询和分页方法(Skip、Take)不能并存
在这个bug得到解决之前,我的列表页看来是不能用Linq做了。
ps: 如果有兴趣研究.NET for Mono 的,我可以提供相关的空间测试环境,有兴趣可加QQ 21979631。
如对本文有疑问,请提交到交流论坛,广大热心网友会为你解答!! 点击进入论坛