ado.net EF作为微软的一个ORM框架,通过实体、关系型数据库表之间的映射,使开发人员可以通过操作表实体而间接的操作数据库,大大的提高了开发效率。
这样一来,.net平台下,我们与底层数据库的交互就有两种选择了(这句话说得不是很准确,微软.net 框架下还是有其他的ORM框架的,,如Nhibernate):ado.net EF、ado.net 。

你可能以为我上面的内容写错了,ado.net EF 、ado.net 两者怎么都带有一个ado.net呢?

OK,如果你有这样的疑问的话,那么我们就有必要来了解一下.net的一些基本知识了

(1).net: 最核心的基础平台(可以看做运行环境和巨多类库),仅次于操作系统
(2)asp.net: .net平台下进行网站开发的框架
(3)asp.net MVC:asp.net 框架下开发网页的一种框架
(4)ado.net: .net平台下访问数据库的框架,他提供了一些列的访问数据库的类库
(5)ado.net EF: ado.net框架下访问数据库的最新最强大的ORM
(6)ORM: 把数据库映射为实体类的技术
(7)NHibemate: .net平台内访问数据库的一种可选ORM,从Java转换而来
以上仅仅是个人见解,不代表官方说法。

上面只是对ado.net 和ado.net EF两者进行了简单了解,下面我们再对两者进行一个具体的比较学习

(1)ado.net 做为原装的直接跟数据库打交道,直接操作数据库,没有进行额外的封装。比如我们可以直接执行sql语句,直接调用存储过程。直接操作DataSet数据集等等数据。
(2)EF 是ORM思想的付诸于实践,它对ado.net进行了封装,对数据表进行了映射处理,以对象的形式展现在开发人员面前。开发人员可以利用Linq语句的优势来执行增、改、查。但是最终的操作都是要转换成SQL语句来执行。比如:

From a in Context.Student
Where a.id =
Select a;

真正执行的时候会转换成 SQL " Select * from Student Where id=1"。
 EF让我们可以用面向对象的思想来编写程序,把注意力集中在系统中的业务环节。但是由于他要进行一次SQL语句的转换,所以相对于原始的ADO.NET来说,EF由于进行了封装,所以性能相对ADO.NET来说差一点点。不过EF也在不断的优化和改进中。 当然,EF也可以直接执行SQL语句和存储过程。有人会问,那为什么不直接执行SQL语句呢,回答是,直接执行的话要EF有什么用呢,EF就是在推行以面向对象编程的思想来处理业务。

OK,上面对两者进行了简单的比较,既然微软对ado.net 进行封装推出EF,那说明EF相对于原始的ado.net还是有优势的呢,那具体有哪些呢?

EF相对于ado.net 的优点
(1)开发效率高,开发人员完全可以根据面向对象的思维进行软件的开发
(2)可以使用三种设计模式中的ModelFirst来设计数据库,而且比较直观
(3)可以跨数据库,只需要在配置文件中修改连接字符串
(4)与vs结合的比较好
缺点:性能上赶不上原生的ado.net (因为他中间还有一个生成sql脚本的过程)

上面的缺点也暴露了一个问题:ado.net EF替代ado.net 。

那有没有折中一点的方案,两者都使用呢?

答案是肯定的,我们可以在EF中使用sql语句,参数化查询和存储过程。那具体如何使用?

ExecuteSqlCommand与SqlQuery

在数据上下文DBModel的实例中有个Database属性,其中有两组方法.ExecuteSqlCommand()和.SqlQuery()。它们都可以执行SQL语句,只不过.ExecuteSqlCommand()是不返回结果的,只返回受影响的行数,所以.ExecuteSqlCommand()更适合执行创建、更新、删除操作。.SqlQuery()则会返回查询到的结果,并将结果保存在数据实体中,所以更适合执行查询操作。

使用.ExecuteSqlCommand()实现创建、更新、删除

.ExecuteSqlCommand()的使用方法也很简单,直接传入SQL语句就可以了,执行完成后会返回受影响的行数。

using (var db = new DBModel()) //创建数据库上下文
{
//同步的方式执行SQL,并返回受影响的行数
int result = db.Database.ExecuteSqlCommand(@"CREATE TABLE `test`.`test` (
`id` INT NOT NULL,
PRIMARY KEY(`id`)); ");
//使用SqlParameter传值可以避免SQL注入
var p_name = new SqlParameter("@name", "萝莉");
var p_age = new SqlParameter("@age", );
//如果使用的是MySql数据库 需要SqlParameter把替换为MySqlParameter
//var p_name = new MySqlParameter("@name", "萝莉");
//var p_age = new MySqlParameter("@age", 13);
//更改学生年龄
result = db.Database.ExecuteSqlCommand(@"UPDATE `test`.`student`
SET `age` = @age
WHERE `name` = @name;", p_age, p_name);
//异步的方式执行SQL,并返回受影响的行数
Task<int> result2 = db.Database.ExecuteSqlCommandAsync("DROP TABLE `test`.`test`;");
}

PS:如果需要创建或删除当前数据库,Database属性中还存在.Create() 和.Delete()方法,它们不接受参数,返回一个bool值表示执行成功或失败。

使用.SqlQuery()查询数据

从名字就看的出来.SqlQuery()是用来执行查询的。.SqlQuery()使用前需指定返回值的数据类型,比如我查询寻一条学生的完整信息,类型就可以指定为student类型。如果是统计有多少个学生,返回值是个整数,就以设置为int。

注意:不仅返回值的个数必须与传入类型中属性值的个数相同,而且名称还必须一样,不然会出错。那么如果我只想获取姓名和年龄,那就得单独定义一个类(其中包含一个string类型的name和int类型的age),来保存数据了。

 
class temp
{
public string name { get; set; }
public int age { get; set; }
}
static void Main(string[] args)
{
using (var db = new DBModel()) //创建数据库上下文
{
//查询叫萝莉的学生信息,并指定返回值类型为student
DbRawSqlQuery<student> result1 = db.Database.SqlQuery<student>("SELECT * FROM test.student WHERE name = '萝莉'");
//也可以这样指定返回值类型
//DbRawSqlQuery result1 = db.Database.SqlQuery(typeof(student), "SELECT * FROM test.student WHERE name = '萝莉'");
Console.WriteLine(result1.FirstOrDefault().name); //打印姓名
DbRawSqlQuery<int> result2 = db.Database.SqlQuery<int>("SELECT count(*) FROM test.student");
Console.WriteLine(result2.FirstOrDefault()); //打印有多少学生
//只查询学生的年龄与姓名
var result3 = db.Database.SqlQuery<temp>("SELECT `name`,`age` FROM test.student;");
foreach (temp item in result3)
{
Console.WriteLine(item.name + ":" + item.age);
}
}

使用DbSet<T>下的.SqlQuery()

在每个数据实体集合DbSet<T>下也有一个.SqlQuery(),功能与上面介绍的一样,只不过DbSet<T>下的.SqlQuery()只能返回DbSet<T>中包含的类型。但DbSet<T>下的.SqlQuery()在返回数据的同时还会让数据库上下文(DBModel)跟踪返回数据的状态,如果返回的数据发生了修改,就可以使用.SaveChanges()将结果直接保存回数据库。而.Database.SqlQuery()查出的结果则是做不到的。

using (var db = new DBModel()) //创建数据库上下文
{
//查询叫萝莉的学生信息,并修改她的年龄
student result1 = db.students.SqlQuery("SELECT * FROM test.student WHERE name = '萝莉'").FirstOrDefault();
result1.age = ; //通过实体集合下.SqlQuery查询到的数据,修改之后是可以保存到数据库的
student result2 = db.Database.SqlQuery<student>("SELECT * FROM test.student WHERE name = '旺财'").FirstOrDefault();
result2.age = ; //因为使用的是.Database.SqlQuery查询到的,所以这里的修改不会保存到数据库
//如果希望.Database.SqlQuery下查出的数据在修改后也能保存到数据库
student result3 = db.Database.SqlQuery<student>("SELECT * FROM test.student WHERE name = '小明'").FirstOrDefault();
result3.age = ;
db.Entry<student>(result3).State = System.Data.Entity.EntityState.Modified; //通知数据上下文,这条记录也被修改了
db.SaveChanges();
}

Ado.net和EF的区别的更多相关文章

  1. ADO,OLEDB,ODBC,DAO的区别【转】

    转载:http://blog.csdn.net/sunboy_2050/article/details/6624684 ODBC(Open Database Connectivity,开放数据库互连) ...

  2. 【转载】ADO,OLEDB,ODBC,DAO的区别

    原文:ADO,OLEDB,ODBC,DAO的区别 ODBC(Open Database Connectivity,开放数据库互连) 1992年,微软公司开放服务结构(WOSA,Windows Open ...

  3. ADO,OLEDB,ODBC,DAO的区别

    ADO NET OLEDB ODBC连接数据库的区别 http://www.doc88.com/p-976312043296.html http://blog.csdn.net/ithomer/art ...

  4. 转:ADO,OLEDB,ODBC,DAO的区别

    ODBC(Open Database Connectivity,开放数据库互连) 1992年,微软公司开放服务结构(WOSA,Windows Open Services Architecture)中有 ...

  5. 数据库连接 ADO,OLEDB,ODBC,DAO的区别 转载

    http://blog.csdn.net/ithomer/article/details/6624684 ODBC(Open Database Connectivity,开放数据库互连) 1992年, ...

  6. ps -aux ,ps aux ,ps -ef 的区别

    Linux中的ps命令是Process Status的缩写.ps命令用来列出系统中当前运行的那些进程.ps命令列出的是当前那些进程的快照,就是执行ps命令的那个时刻的那些进程,如果想要动态的显示进程信 ...

  7. 有关linqtosql和EF的区别

    LINQ to SQL和Entity Framework都是一种包含LINQ功能的对象关系映射技术.他们之间的本质区别在于EF对数据库架构和我们查询的类型实行了更好的解耦.使用EF,我们查询的对象不再 ...

  8. 存储过程分页 Ado.Net分页 EF分页 满足90%以上

    存储过程分页: create proc PR_PagerDataByTop @pageIndex int, @pageSize int, @count int out as select top(@p ...

  9. ps aux和ps -ef命令区别

      ps aux 是用BSD的格式来显示 java这个进程 显示的项目有:USER,PID,%CPU,%MEM,VSZ,RSS,TTY,STAT,START,TIME,COMMAND   ps -ef ...

随机推荐

  1. 归并排序(递归排序and外排排序)

    分析: /** * 归并排序 (先将数组利用归并排序排成 有序的左边数组和右边数组,再比较左边数组和右边数组的数值大小进行排序) * */ public class MergeSort { publi ...

  2. ABP框架系列之五十三:(Web-API-Controllers-Web-API-控制器)

    Introduction ASP.NET Boilerplate is integrated to ASP.NET Web API Controllers via Abp.Web.Api nuget ...

  3. w7 全网架构-rsync-备份

    准备 1.从安装系统开始准备 安装过程中添加网卡 eth0 ip 10.0.0.210 netmask 24 gateway 10.0.0.254 eth1 ip 172.16.1.210 netma ...

  4. VsCode编写和调试.NET Core

    本文转自:https://www.cnblogs.com/Leo_wl/p/6732242.html 阅读目录 使用VsCode编写和调试.NET Core项目 回到目录 使用VsCode编写和调试. ...

  5. easy ui Uncaught Error: cannot call methods on tooltip prior to initialization; attempted to call method 'hide'

    今天bootstrap 和easy ui混用时候报了这么一个错误,本来可以点击编辑的,但是现在一点击就报错,

  6. 用jstack自动化捕抓异常java代码脚本

    #!/bin/bashdate=` date +%y%m%d-%H%M`pid=`top -bn1 |grep java | awk '{print $1 "\t" $9}' |h ...

  7. st-link调试和下载程序(待写)

    st-link调试只用三根线 GND SWCLK SWDIO

  8. QT在Linux下的安装

    QT是一个跨平台的C++开发库,设计思想是同样的,C++无需修改就可以在windows.linux.macOS等平台上使用,他使开发更专注于构建软件的核心价值,而不是维护API.作为面向对象的框架,它 ...

  9. shell 命令 zip unzip

    工作当中,经常要用到zip压缩. zip 将文件夹打包: 如文件夹名 xxx zip -r xxx.zip xxx unzip unzip -o xxx.zip -o 覆盖原有的文件夹 查询更多参数: ...

  10. 04SQL 查询当天,本月,本周的记录

    SQL 查询当天,本月,本周的记录   SELECT * FROM 表 WHERE CONVERT(Nvarchar, dateandtime, 111) = CONVERT(Nvarchar, GE ...