新增
添加命名空间引用 System.Data.Entity.Infrastructure:
#region 新增 static int Add() { using (NorthwindEntities db = new NorthwindEntities()) { Customers cus = new Customers { CustomerID = "zouqj", Address = "南山区新能源创新产业园", City = "深圳", Phone = "15243641131", CompanyName = "深圳跨境翼电商商务有限公司", ContactName = "邹琼俊" }; //方法一 //db.Customers.Add(cus); //方法二(还是方法一简单一些) DbEntityEntry<Customers> entry = db.Entry(cus); entry.State = System.Data.Entity.EntityState.Added; return db.SaveChanges(); } } #endregion
查询
简单查询和延时加载
“延迟加载”有两种形式:
(1)EF 本身查询方法返回的都是 IQueryable 接口,此时并未查询数据库。只有当调用接口方法获取数据时,才会查询数据库。
static void QueryDelay1() { using (NorthwindEntities db = new NorthwindEntities()) { DbQuery<Customers> dbQuery = db.Customers.Where(u => u.ContactName == "邹琼俊").OrderBy(u => u.ContactName).Take(1) as DbQuery<Customers>; //延迟查询对象 //获得延迟查询对象后,调用对象的获取方法,此时就会根据之前的条件生成SQL语句,查询数据库了! Customers cus = dbQuery.FirstOrDefault(); Console.WriteLine(cus.ContactName); } }
(2)当前可能通过多个标准查询运算符方法来组合查询条件,那么每个方法都只是添加一个查询条件而已,无法确定本次查询条件是否已经添加结束,所以没有办法在执行每个 SQO 方法的时候确定 SQL 语句是什么,
只能返回一个包含了所有添加条件的 DBQuery 对象,就相当于一直在拼接 SQL 语句但是不执行,只有当使用这个 DBQuery 对象的时候才根据所有条件生成 SQL 语句,最终查询数据库。
static void QueryDelay2() { using (NorthwindEntities db = new NorthwindEntities()) { IQueryable<Orders> orders = db.Orders.Where(u => u.CustomerID == "alfki"); //以接口方式返回的 DBQuery 对象 //此时只查询了订单表 Orders order = orders.FirstOrDefault(); //当访问订单对象里的外键实体时,EF会查询订单对应的用户表,查到之后再将数据装入这个外键实体 Console.Write(order.Customers.ContactName); IQueryable<Orders> orderList = db.Orders; foreach(Orders o in orderList) { Console.WriteLine(o.OrderID + ":ContactName=" + o.Customers.ContactName); } } }
延迟加载的缺点是每次调用外键实体时都会去查询数据库,不过 EF 有小优化,即相同的外键实体只查一次。
禁用延迟的方法有 ToList()、FirstOrDefault()、Include() 等。
通常在多层架构中,数据访问层都会返回 IQueryable,业务逻辑层根据需要转为 List,这样可以有更多的选择。
根据条件排序和查询
#region 根据条件排序和查询 /// <summary> /// 根据条件排序和查询 /// </summary> /// <typeparam name="TKey">排序字段类型</typeparam> /// <param name="whereLambda">查询条件 Lambda 表达式</param> /// <param name="orderLambda">排序条件 Lambda 表达式</param> /// <returns></returns> public List<Customers> GetListBy<TKey>(Expression<Func<Customers, bool>> whereLambda, Expression<Func<Customers, TKey>> orderLambda) { using (NorthwindEntities db = new NorthwindEntities()) { return db.Customers.Where(whereLambda).OrderBy(orderLambda).ToList(); } } #endregion
分页查询
#region 分页查询 /// <summary> /// 分页查询 /// </summary> /// <typeparam name="TKey"></typeparam> /// <param name="pageIndex">页码</param> /// <param name="pageSize">页容量</param> /// <param name="whereLambda">条件 Lambda 表达式</param> /// <param name="orderBy">排序 Lambda 表达式</param> /// <returns></returns> public List<Customers> GetPagedList<TKey>(int pageIndex,int pageSize, Expression<Func<Customers,bool>> whereLambda, Expression<Func<Customers, TKey>> orderBy) { using (NorthwindEntities db = new NorthwindEntities()) { //分页时一定要注意:Skip 之前一定要 OrderBy return db.Customers.Where(whereLambda).OrderBy(orderBy).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList(); } } #endregion
修改
关于数据修改,微软官方推荐的修改方式是先查询再修改。
#region 官方推荐的修改方式(先查询,再修改) /// <summary> /// 官方推荐的修改方式(先查询,再修改) /// </summary> static void Edit() { using (NorthwindEntities db = new NorthwindEntities()) { // 1.查询出一个要修改的对象 -- 注意:此时返回的是一个 Customers 类的代理类对象(包装类对象) Customers cus = db.Customers.Where(u => u.CustomerID == "alfki").FirstOrDefault(); Console.WriteLine("修改前:" + cus.ContactName); // 2.修改内容 -- 注意:此时其实操作的是代理对象的属性,这些属性会将值设置给内部的 Customers 对象对应的属性,同时标记此此属性为已修改状态 cus.ContactName = "邹玉杰"; // 3.重新保存到数据库 -- 注意:此时 EF 上下文会检查容器内部所有的对象,先找到标记为已修改的对象,然后找到标记为修改的对象属性,生成对应的 update 语句执行 db.SaveChanges(); Console.WriteLine("修改成功:"); Console.WriteLine(cus.ContactName); } } #endregion
自己优化的修改方式(创建对象,直接修改)
#region 自己优化的修改方式(创建对象,直接修改) /// <summary> /// 自己优化的修改方式(创建对象,直接修改) /// </summary> static void Edit2() { // 1.查询出一个要修改的对象(感觉不对,不是创建吗?但是把所有字段都创建出来好像并不合适) Customers cus = new Customers { CustomerID = "zouqj", Address = "南山区新能源创新产业园", City = "深圳", Phone = "15243641131", CompanyName = "深圳跨境翼电商商务有限公司", ContactName = "邹玉杰" }; using (NorthwindEntities db = new NorthwindEntities()) { // 2.将对象加入 EF 容器(执行 Entry 方法),并获取当前实体对象的状态管理对象(方法的返回值) DbEntityEntry<Customers> entry = db.Entry(cus); // 3.设置该对象为未修改过 entry.State = System.Data.Entity.EntityState.Unchanged; // 4.设置该对象的 ContactName 属性为修改状态 (同时 entry.State 被修改为 Modified 状态) entry.Property("ContactName").IsModified = true; //var u = db.Customers.Attach(cus); //u.ContactName = "郭富城"; // 5.重新保存到数据库 -- EF 上下文会根据实体对象的状态 entry.State = Modified 值生成对应的 update sql 语句 db.SaveChanges(); Console.WriteLine("修改成功:"); Console.WriteLine(cus.ContactName); } } #endregion
删除
#region 删除 /// <summary> /// 删除 /// </summary> static void Delete() { using (NorthwindEntities db = new NorthwindEntities()) { // 1.创建要删除的对象 Customers cus = new Customers() { CustomerID = "zouqj" }; // 2. 附加到 EF 中 db.Customers.Attach(cus); // 3.标记为删除 -- 注意:此方法就是标记当前对象为删除状态 db.Customers.Remove(cus); /* 也可以使用 Entry 来附加和修改 DbEntityEntry<Customers> entry = db.Entry(cus); entry.State = System.Data.Entity.EntityState.Deleted; */ //执行删除 SQL db.SaveChanges(); Console.WriteLine("删除成功!"); } } #endregion
批处理
在批处理中,我们能深深体会到上下文对象中 SaveChanges 方法的好处。
#region 批处理 /// <summary> /// 批处理 /// </summary> static void SaveBatched() { // 1.新增数据 Customers cus1 = new Customers { CustomerID = "zouyujie", Address = "洛阳西街", City = "洛阳", Phone = "1314520", CompanyName = "微软", ContactName = "邹玉杰" }; using (NorthwindEntities db = new NorthwindEntities()) { db.Customers.Add(cus1); // 2.新增第二个数据 Customers cus2 = new Customers { CustomerID = "zhaokuangyin", Address = "洛阳西街", City = "洛阳", Phone = "1314520", CompanyName = "微软", ContactName = "赵匡胤" }; db.Customers.Add(cus2); // 3.修改数据 Customers usr = new Customers() { CustomerID = "zhaomu", ContactName = "赵牧" }; DbEntityEntry<Customers> entry = db.Entry(usr); entry.State = System.Data.Entity.EntityState.Unchanged; entry.Property("ContactName").IsModified = true; // 4.删除数据 Customers u = new Customers() { CustomerID = "zouyujie" }; db.Customers.Attach(u); //附加到 EF 中 db.Customers.Remove(u); //标记为删除 -- 此方法就是标记当前对象为删除状态 db.SaveChanges(); Console.WriteLine("批处理 完成~~~~~~~~!"); } } #endregion
批处理 -- 一次新增 50 条数据
#region 批处理 -- 一次新增 50 条数据 /// <summary> /// 批处理 -- 一次新增 50 条数据 /// </summary> static void BatcheAdd() { using (NorthwindEntities db = new NorthwindEntities()) { for(int i=0;i<50;i++) { Customers cus = new Customers { CustomerID = "zou" + i, Address = "洛阳西街", City = "洛阳", Phone = "1314520", CompanyName = "微软", ContactName = "邹玉杰" + i }; db.Customers.Add(cus); } db.SaveChanges(); } } #endregion