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. Python语言中的按位运算

    (转)位操作是程序设计中对位模式或二进制数的一元和二元操作. 在许多古老的微处理器上, 位运算比加减运算略快, 通常位运算比乘除法运算要快很多. 在现代架构中, 情况并非如此:位运算的运算速度通常与加 ...

  2. async/await让你的代码更加优雅

    一. 回调地狱:回调函数里面嵌套着回调函数嵌套着回调函数”,这就是被传说中的“回调地狱callbackHell () { const api = new Api() let user, friends ...

  3. JavaScript基础视频教程总结(011-020章)

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...

  4. verilog 有符号数(2转)

    在数字电路中,出于应用的需要,我们可以使用无符号数,即包括0及整数的集合:也可以使用有符号数,即包括0和正负数的集合.在更加复杂的系统中,也许这两种类型的数,我们都会用到. 有符号数通常以2的补码形式 ...

  5. Paper | 帧间相关性 + 压缩视频质量增强(MFQE)

    目录 1. ABSTRACT 2. INTRODUCTION 3. RELATED WORKS 3.1. Quality Enhancement 3.2. Multi-frame Super-reso ...

  6. MFC 多窗口通信时,使用RadioButton和Button时冲突问题

    最近项目需要我们实现在两个窗口间进行通信,其中有个小功能如图所示: 当我点击GDIProgram中的Button1时,会更新Dialog的Radio1和Radio2的状态. Dialog中的Radio ...

  7. ios webview下footer部分fixed失效问题

    场景: 如下图所示,一个很正常的页面需求,footer固定在底部,中间为滚动内容区 然后footer的css一般是这样的 footer{ position:fixed; bottom:; left:; ...

  8. 软件测试人员需要掌握的linux命令(一)

    有些技能可以事半功倍,熟练的使用这些命令可以提高工作效率,并且结合这些命令对测试过程中遇到的问题进行一些初步的定位. 一:目录与文件操作: ls 使用权限:所有人功能 : 显示指定工作目录下之内容(列 ...

  9. 鱼眼投影方式(Fisheye projection)的软件实现

    简单实现 鱼眼模式(Fisheye)和普通的透视投影(Perspective projection),一个很大的区别就是鱼眼的投影算法是非线性的(non-linear),实际照相机的情况是在镜头外面包 ...

  10. 一个简单的C语言题背后的故事

    最近看到了一个C语言问题,是要计算出这个函数的输出: #include <stdio.h> int Test(int x,int y, int z){ printf("x,y,z ...