10
2014
03

EntityFrameWork使用MySql数据库分页的BUG

环境

使用MySQL Connector NET 6.7.4+EF5.0+VS2010

问题描述

 

IQueryable<T>类型的Where方法和Skip或Take方法一起使用时,生成的SQL语句错误。

详细代码

首先定义一个Model

1 public class User2 {3     public string Id { set; get; }4     public string Name { set; get; }5 }

运行如下程序,本意是要查询User表中Name包含"Test"的记录,并返回前10条:

1 string Name = "Test";2 var Data = db.Set<User>().Where<User>(o => o.Name.Contains(Name)).3     OrderBy<User,string>(o=>o.Id).4     Skip<User>(0).5     Take<User>(10);

运行后抛出"执行命令定义时出错。有关详细信息,请参阅内部异常",调试发现生成的SQL如下:

1 SELECT2 `Project1`.`Id`, 3 `Project1`.`Name`4 FROM `User` AS `Project1`5  WHERE (LOCATE(@p__linq__0, `Extent1`.`Name`)) > 06  ORDER BY 7 `Project1`.`Id` ASC LIMIT 0,10

原来生成的SQL中根本就没有 Extent1 这个别名,所以查询的时候自然就报错误,将代码修改成这样(即将变量直接换成文字):

1  var Data = db.Set<User>().Where<User>(o => o.Name.Contains("Test")).2       OrderBy<User,string>(o=>o.Id).3       Skip<User>(0).4       Take<User>(10);

生成的SQL为:

1 SELECT2 `Extent1`.`Id`, 3 `Extent1`.`Name`4 FROM `User` AS `Extent1`5  WHERE `Extent1`.`Name` LIKE '%Test%'6  ORDER BY 7 `Extent1`.`Id` ASC LIMIT 0,10

运行结果正常。

之后将数据源换成SQL Server数据库后 同样的写法也一切正常,不知道这是不是MySql.Data.Entity生成SQL的一个BUG

 

解决办法

抱着试试的态度,将Where方法放到Take方法后即:

1 string Name = "Test";2 var Data = db.Set<User>().OrderBy<User,string>(o=>o.Id).Skip<User>(0).Take<User>(10).Where<User>(o => o.Name.Contains(Name));

生成的SQL为:

 1 SELECT 2 `Project1`.`Id`,  3 `Project1`.`Name` 4 FROM (SELECT 5 `Extent1`.`Id`,  6 `Extent1`.`Name` 7 FROM `User` AS `Extent1` 8  WHERE (LOCATE(@p__linq__0, `Extent1`.`Name`)) > 0 9  ORDER BY 10 `Extent1`.`Id` ASC LIMIT 0,10) AS `Project1`11  ORDER BY 12 `Project1`.`Id` ASC

Ok,运行,正常了。


« 上一篇下一篇 »

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。