本来EF的存在对于单/多表查询是灰常方便的,但是新手(比如我这种半吊子)有时候Lambda表达式憋了半天憋不出来,LINQ又不是很会写,领导又催的急,项目还要移植过去,又来不及进行统一规范。想想都要急死人,这时候完全可以用熟悉的SQL语句代替,只需把查询语句复制过去就能得到结果了,岂不妙哉。
这篇文章将记录我目前常用的查询方法,之前花了一些时间整理出来了,分享给大家。
首先需要新建一个项目,并使用之前文章所说的方法,建立一个来自数据库的Code First 实体模型。请注意,在项目移植的时候,对于之前的项目所使用的数据库中的表,如果有一些表没有设定主键,可能是无法生成实体模型的。为了养成良好的习惯,在设计数据库的时候最好将表设定一个主键,反正设了也没啥坏处嘛。
查询的方法有很多种。
1、使用Lambda表达式查询数据。
对于简单的Lambda表达式,这样是很简单很轻松的,但是如果是多表的联合查询,从代码的可读性上来说,还是不建议使用的。
Lambda表达式
上面截图中使用的是Lambda表达式查询出单个对象,然后取出需要的数据。
2、使用Linq To Entities。
其实也就是Linq啦,只不过取了个牛逼的名字而已(我是酱紫认为滴)。如果想要查询出上面相同的数据,使用Linq也是比较简单的。然后就可以使用Linq的语法,写各种不同的查询条件了。
Linq
3、使用SQL语句
你可能会有疑问,我用EF不就是为了不写SQL语句吗,现在又要我写SQL语句,那我干嘛不直接使用ADO.NET得了。话虽如此,但是EF也有不是很方便的地方,比如想要删除一些数据,按照EF的套路,我们必须要先查询出这个集合,然后逐条删除,虽然效果达到了,但是效率不是很高。再比如我目前项目中遇到的一个问题,之前的报表查询使用的是SQL语句,但是有些报表牵扯到好几个表,导致我憋Lambda和Linq憋了很久,然后索性使用SQL语句,直接复制过来,使用EF的SqlQuery一步到位。但是EF总的来说是非常方便的,只需要SaveChanges就完成了所有的更改,我认为其利大于弊吧。
看一个例子:
SQL
如果是查询一个完整的对象,只需使用相应的实体模型UserInfo即可,因为只有一条数据,就在后面加上了FirstOrDefault方法。但是如果只查询几个字段,那这个方法就会报错,那就不可行了,见下图:
报错
因此需要使用第二种方法DataBase,创建一个类User,User表中有我需要查询出来的属性,注意,这里的属性名称需要与查询出来的名字相同,而且得一模一样,否则是不会显示出来的,虽然它也不会报错。
User
另外说明一句,如果出于安全性,请考虑在使用SqlQuery时对输入参数化,防止SQL注入攻击(这是微软说的)。
4、调用存储过程
这里我随便写的一个简单的存储过程,若存在数据返回1,不存在返回0,看看EF应该如何执行存储过程。
存储过程
如果是DBFirst的话,存储过程都可以生成一个方法,直接跟调用方法一样调用存储过程。但是CodeFirst没有这个功能,这时候就可以使用SqlQuery调用存储过程,返回的结果是什么类型,尖括号中的泛型就表示什么类型。如果返回的是一个集合,那么尖括号中就是集合中元素的数据类型。这里我的返回是int,因此,我的泛型就是int。如下图,结果输出为1。
SqlQuery执行存储过程
5、EF进行多表查询
这里我推荐使用Linq和SQL语句。Linq的思路就是各种join,然后把查询条件写清楚就能得出结果。SQL语句的思路就是类似第三步中的方法,新创建一个类作为泛型的类型,不管查询出来的是什么结果,都可以使用这种方法,很方便。下面给出了两种思路的简单代码供参考。
多表查询
总结:对于有强迫症的人来说在EF中使用SQL估计很难让他接受,但是这两个本就是一家,大家和气共处岂不美哉?!