您现在的位置: 365建站网 > 365学习 > 关于Mono使用linq查询的几个BUG

关于Mono使用linq查询的几个BUG

文章来源:365jz.com     点击数:256    更新时间:2011-06-19 00:39   参与评论

服务器环境如下:
系统: Ubuntu 10.10
Web服务器:Jexus/4.2.3 Linux
Mono版本: Mono 2.10.1

代码如下:

View Code
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下就出错了,报出如下的错误。

Server Error in '/' Application


 System.ArgumentException: New 

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;

继续运行,继续报错。

Server Error in '/' Application


')' 附近有语法错误。

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。

如对本文有疑问,请提交到交流论坛,广大热心网友会为你解答!! 点击进入论坛


发表评论 (256人查看0条评论)
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
用户名: 验证码: 点击我更换图片
最新评论
------分隔线----------------------------