EntityFramework学习笔记4-实体数据模型及增、删、改操作

下面我们通过建立一个简单的例子来学习EF框架,直接进入主题吧:

一 、创建实体数据模型

1. 创建一个控制台应用程序,起名为EFDemo

2. 创建一个实体模型

  在EFDemo项目上面右击选择添加—新建项—在已安装的选项中选择数据—ADO.NET实体对象模型,命名为EFStudy

3. 与数据库连接

  第2步执行完毕会弹出向导,选择“从数据库生成”,点击“新建连接…”按钮,选择sql server,下略,测试连接成功后,确定返回,注意下方的App.Config会自动生成一个数据库名+Entities的名字,此名字会成为上下文的类名,建议修改为***+Context,比如PopContext,然后点击下一步

4. 指定相应的库表、视图和存储过程生成实体

勾选对应的库表、视图和存储过程生成实体,点击完成即可。

注:可事先在sql server数据库中使用以下语句建一张简单的表

CREATE TABLE [dbo].[SysDept](
[ID] [varchar](16) primary key,
[Name] [varchar](64) NOT NULL
)
GO

以上步骤操作完毕后,在项目中新增文件EFStudy.edmx,并以图形化方式显示SysDept类

二、增删改操作

1.新增

因为前面创建的是控制台应用程序,且为了清晰,只引入了一张表,代码也从简,直接在Program.cs里面写

static void Main(string[] args)
        {
            //新增
            InsertDept();
        }

        private static void InsertDept()
        {
            //数据库表SysDept已经被EF映射为了SysDept类
            //此处可直接使用来定义对象
            SysDept sysDept = new SysDept();
            //为对象设置属性
            sysDept.ID = "1";
            sysDept.Name = "烟台**公司";

            //EF已经创建了上下文对象,类名为创建实体类型阶段指定的PopContext
            PopContext context = new PopContext();
            //将sysDept对象加入到上下文对象,三种方式
            //方式一(推荐)
            context.SysDept.AddObject(sysDept);
            //方式二
            //context.AddToSysDept(sysDept);
            //方式三
            //context.AddObject("SysDept", sysDept);


            //以上操作后数据变更在内存中,执行以下操作后保存到数据库
            int i=context.SaveChanges();
            Console.WriteLine("影响行数:"+i);

        }

如上所示,将实体对象添加到上下文对象有三种方式,推荐第一种,符合习惯和自然,第二种在库表比较多的情况下,难以查找,第三种第一个参数采用字符串,易拼写错误且繁琐

使用sql server 自带的SQL Server Profiler(开始—》SQL Server 2008-》性能工具,若找不到,说明你安装的sql server版本是express,开发版和企业版都有该工具),可查看数据库执行的每条sql,即可以观察上述程序执行时,EF将程序中对对象的操作转换为具体的sql语句,对于初期阶段理解学习以及后期的多表关联下性能调优大有益处。

 

2.删除

 要删除某条记录,就要先找到该条记录,有两种方式,一是定义一个新对象,通过Context的Attach方法将该对象加入管理,如下面代码所示,二是在上下文对象中查找,代码在修改例子中体现

        private static void DeleteDept()
        {
            //先定义一个新对象并设置主键属性
            SysDept sysDept = new SysDept();            
            sysDept.ID = "1";

            //将此对象附加到上下文对象
            PopContext context = new PopContext();
            context.SysDept.Attach(sysDept);

            //移除对象,两种方法
            //方法一,推荐
            context.SysDept.DeleteObject(sysDept);
            //context.DeleteObject(sysDept);//方法二

            //以上操作后数据变更在内存中,执行以下操作后保存到数据库
            int i = context.SaveChanges();
            Console.WriteLine("影响行数:" + i);    
        
        }

网上查找资料,发现好多是以下两种方式,可能在早期版本支持,在EF5.0中已过时,context既无Entry方法,也无Remove方法,sysDept.EntityState属性只读,不可设置

1.context.Entry(sysDept).State = EntityState.Deleted;//EntityState枚举值需using System.Data;
2.context.SysDept.Remove(sysDept)

 3.修改

  要修改某条记录,就要先找到该条记录

 

private static void UpdateDept()
        {
            //找到要修改的记录,查找参数为lamda表达式,看不懂的可补习相关知识
            PopContext context = new PopContext();
            SysDept sysDept = context.SysDept.FirstOrDefault(dept => dept.ID == "1");
            //修改属性
            sysDept.Name = "青岛**公司";

            //以上操作后数据变更在内存中,执行以下操作后保存到数据库
            int i = context.SaveChanges();
            Console.WriteLine("影响行数:" + i);    
        }

 

这里体现了上文所说查找记录的第二种方式,事实上,采用这种方式先找到对象,再对对象进行删除或者修改操作更符合常理。

同删除类似,EF5.0中已没有context.Entry(sysDept).State = EntityState.Modified的写法

4.事务处理

上面说了增、删、改,程序中常用到的还有事务处理,与do.net处理类似

        private static void Transaction()
        {
            PopContext context = new PopContext();
            IDbTransaction trans = null;
            try
            {                
                //打开连接
                context.Connection.Open();
                //开始事务
                trans=context.Connection.BeginTransaction();
                //执行操作
                //修改一记录
                SysDept sysDept = context.SysDept.FirstOrDefault(dept => dept.ID == "1");
                sysDept.Name = "临沂****公司";
                //新增一记录
                sysDept = new SysDept { ID = "2", Name = "菏泽***公司" };
                context.SysDept.AddObject(sysDept);         
                //保存到数据库
                int i=context.SaveChanges();
                //提交事务
                trans.Commit();
                Console.WriteLine("已成功执行,影响行数:"+i);                
            }
            catch (Exception ex)
            {
                trans.Rollback();
                Console.WriteLine("发生异常,已回滚" + ex.Message);
            }
            finally
            {
                context.Connection.Close();
            }
           
        }

上述过程第一次执行正常提交,把sysDept.Name = "临沂****公司";中“临沂”改为“日照”,再执行一次,则会因为重复插入主键异常退出,查看数据库会发现,不仅新数据没插进去,而且在插入数据之前修改的数据也没有保存到数据库,从而说明实现了回滚功能。
注意:此处回滚仅对数据库有效,内存中PopContext对象中的"临沂****公司"已经被更改了,回滚不会将内存中的数据恢复到事务前状态。

 三、小结
从本节内容就能看出ORM的优点了,在程序中一方面不需要再写与数据库对应的的INSERT/DELETE/UPDATE的SQL语句,特别是在表字段比较多的情况下,写一个比较长的Insert语句,很容易发生错位、缺失问题,另一方面可以直接实例化对象,获取或者设置属性值时,智能提示很友好也很便利。

posted on 2012-11-28 22:30  大浪淘沙  阅读(4784)  评论(3编辑  收藏  举报

导航