前言
在以前学习和使用WinForm、ASP.NET WebForm、三层架构的时候,对于数据访问的实现,无论是什么逻辑,简单还是复杂,无论是执行SQL语句还是调用存储过程都要用到ADO.NET技术,通过封装好的SQLhelper类传入SQL语句和SqlParameter参数来操作数据库,使用起来还是有点麻烦呐~~~
随着.Net学习的不断深入,学习过ASP.NET MVC知识体系时才逐渐开始了解和使用微软ORM系列的Entity Framework框架,通过使用EF可以方便快捷的操作数据库。我一共学习和使用了三种模式的EF(DBFirst[数据库优先]、ModelFirst[模型优先]、CodeFirst[代码优先]),最初学习时从ADO.NET向EF的转变过程也不是很轻松,这里对EF的各种增删改查方法做一次系统的总结和巩固,方便自己以后温故知新,也可以帮助小白快速入门。
这里使用DBFirst EF 6.0对一张表进行描述(#^.^#)
EF上下文对象:
表中对应字段:(我用了一个十几年前的商品数据库,里面的字段名都是拼音缩写,不要效仿前辈们的陋习O(∩_∩)O哈哈~)
一、查询
EF中我们可以使用三种方式进行查询操作:Linq语句、Linq方法和SQL语句,这三种方法我会逐一进行说明。
①查询全表数据
这里为了查看结果方便,都使用ToList()结束了延迟加载。
1.方法一:Linq方法
var list = entities.T_Spb.Select(s=>s).ToList();
var list = entities.T_Spb.ToList();
2.方法二:Linq语句
var list = (from item in entities.T_Spb
select item).ToList();
3.方法三:SQL语句
var list = entities.T_Spb.SqlQuery("select * from T_Spb").ToList();
var list = entities.Database.SqlQuery("select * from T_Spb").ToList();
注:三者种方法结果相同,但是ToList()之前的返回值类型是不一样的。方法一、方法二(使用Linq)返回值类型为IQueryable<T>,方法三中DbSet.SqlQuery()返回值类型为DbSqlQuery<T>,database.SqlQuery()返回值类型为DbRawSqlQuery<T>。
②查询单个数据
查询id为30的商品
特殊:Find方法根据要查找的实体的主键值查对象。若通过主键查,用Find()比较方便。
var model = entities.T_Spb.Find(30);
1.方法一:Linq方法
var model = entities.T_Spb.Where(s => s.SpID == 30).FirstOrDefault();
var model = entities.T_Spb.FirstOrDefault(s => s.SpID == 30);//上面的简写形式
注:查询单个数据时,可以使用First()、FirstOrDefault()、Single()、SingleOrDefault()
1. First 返回第一条数据 结果为空时出异常 FirstOrDefault 返回序列第一条数据 数据为空返回null
2. Single SingleOrDefault 返回序列第一条数据 多条结果时出异常
2.方法二:Linq语句
var model = (from s in entities.T_Spb
where s.SpID == 30
select s).FirstOrDefault();
3.方法三:SQL语句
var model = entities.T_Spb.SqlQuery("select * from T_Spb where spid=30").FirstOrDefault();
var model = entities.Database.SqlQuery<T_Spb>("select * from T_Spb where spid=30").FirstOrDefault();
③查询部分数据(带条件的查询)
例:模糊查询 查询商品名称中含有 霸王 的商品
1.方法一:Linq方法
var list = entities.T_Spb.Where(s => s.Spmc.Contains("霸王")).ToList();
2.方法二:Linq语句
var list = (from s in entities.T_Spb
where s.Spmc.Contains("霸王")
select s).ToList();
3.方法三:SQL语句
var list = entities.T_Spb.SqlQuery("select * from T_Spb where Spmc like '%霸王%'").ToList();
var list = entities.Database.SqlQuery<T_Spb>("select * from T_Spb where Spmc like '%霸王%'").ToList();
④查询部分字段
1.方法一:Linq方法
var list = entities.T_Spb.Select(s => new { id = s.SpID, name = s.Spmc}).ToList();
2.方法二:Linq语句
var list1 = (from s in entities.T_Spb
select new
{
id = s.SpID,
name = s.Spmc
}).ToList();
因为查询部分字段要返回一个匿名类对象,调用SQL语句要指明类型,这里就不写调用SQL啦!
二、添加
1.方法一:Add()
var model = new T_Spb() { Spmc = "防脱发神器", Spgg = "ml", Spdw = "瓶", Splb = 2, Sptxm = "0000000000", Spbz = "程序员必备" };
entities.T_Spb.Add(model);
entities.SaveChanges();
2.方法二:修改State状态
注:EF中的实体的状态值有Detached、Unchanged、Added、Deleted、Modified五种,可以通过修改上下文中实体的State值来实现 相应增删改操作。
var model= new T_Spb() { Spmc = "防脱发神器1", Spgg = "ml", Spdw = "瓶", Splb = 2, Sptxm = "0000000001", Spbz = "程序员必备" };
entities.Entry(model).State = System.Data.Entity.EntityState.Added;
entities.SaveChanges();
3.方法三:执行SQL语句
entities.Database.ExecuteSqlCommand("sql");//返回受影响行数
三、删除
删除主键为50的商品
1. 方法一:Remove()【先查找再删除,操作数据库两次】
var model = entities.T_Spb.Find(50);
entities.T_Spb.Remove(model);
entities.SaveChanges();
2.方法二:修改State状态【直接删除操作数据库一次】
var model = new T_Spb() { SpID = 50 };
entities.Entry(model1).State = System.Data.Entity.EntityState.Deleted;
entities.SaveChanges();
注意事项①:
若直接实例化一个实体对象【不是查出来的】,直接使用Remove()方法,则会引发异常。
解释:Remove()操作的对象必须在EF上下文中,直接new的实体对象是不在上下文中的。
解决办法:通过Attach()方法 将实例化的model添加到EF上下文对象即可!
注意事项②:
若不指定主键值,直接修改State值去删除也会引发异常。
解释:EF上下文中通过主键对实体对象进行跟踪,因此修改State值删除时要指明主键。
解决办法:指定主键值
四、修改
1.方法一 修改部分字段 (先查再修改)
var model = entities.T_Spb.FirstOrDefault(x=>x.SpID==30);
model.Sptxm = "10241024";
entities.SaveChanges();
2.方法二:修改全部字段【设置State状态跟删除一样,要指明主键】
注意:这种更新会将实例化的新对象中的值全部更新到数据库中,未赋值的字段为更新为null值
var model2 = new T_Spb { SpID = 42,Sptxm="10241024" };
entities.Entry(model2).State = System.Data.Entity.EntityState.Modified;//全部更新
entities.SaveChanges();
若想采用方法二修改部分字段可以先将实例化model添加到上下文中,设定某一字段的IsModified属性来实现
var model2 = new T_Spb { SpID = 45,Sptxm="10241024" };
entities.T_Spb.Attach(model2);
entities.Entry(model2).Property("Sptxm").IsModified = true;
entities.SaveChanges()
结语
以上就是EntityFramework 中单表基本增删改查的各种方法在不同情况下的使用和详细说明,每种Linq语句对应的Linq方法也都写出,关键部分和使用时的注意事项都做了着重解释。对EF CRUD做了细致的总结,为了自己以后出问题时及时更新,也可以帮助大家对EF的增删改查有个系统性的了解,同时也可以帮助志同道合的同学快速入门!
以上概述都来自平时的学习和开发积累,都是个人的一些看法和心得,若有出入可以参照Microsoft官方文档进一步学习吖!