EF之增删改查
增成功后EF容器里面的实体不会被销毁,EF查询出来的都是代理类对象或集合
//1.0 创建实体 BlogUser usrModel = new BlogUser() { LoginName = "xiaobai1", LoginPwd = "4297F44B13955235245B2497399D7A93", CnName = "小白", Email = "xiaobai@oumind.com", IsDel = false, IsLock = 0, AddTime = DateTime.Now, LastLoginIP = "127.0.0.1", LastLoginTime = DateTime.Now }; //2.0 调用EF容器,向指定的 属性中(表) 添加实体对象 db.BlogUsers.Add(usrModel); //3.0 调用EF容器的 SaveChanges方法,将容器里的对象 保存到数据库,并返回受影响行数! int resCount = db.SaveChanges(); //4.0 新增后,主键属性Id,会被赋值(新增后的id) MessageBox.Show(usrModel.Id.ToString());
1 批量添加 2 //1.0 创建实体1 3 BlogUser usrModel = new BlogUser() 4 { 5 LoginName = "xiaobai2", 6 LoginPwd = "4297F44B13955235245B2497399D7A93", 7 CnName = "小白2", 8 Email = "xiaobai2@oumind.com", 9 IsDel = false, 10 IsLock = 0, 11 AddTime = DateTime.Now, 12 LastLoginIP = "127.0.0.1", 13 LastLoginTime = DateTime.Now 14 }; 15 16 //1.0 创建实体2 17 BlogUser usrModel2 = new BlogUser() 18 { 19 LoginName = "xiaobai3", 20 LoginPwd = "4297F44B13955235245B2497399D7A93", 21 CnName = "小白3", 22 Email = "xiaobai3@oumind.com", 23 IsDel = false, 24 IsLock = 0, 25 AddTime = DateTime.Now, 26 LastLoginIP = "127.0.0.1", 27 LastLoginTime = DateTime.Now 28 }; 29 30 db.BlogUsers.Add(usrModel); 31 db.BlogUsers.Add(usrModel2); 32 int resCount = db.SaveChanges(); 33 MessageBox.Show("受影响行数:" + resCount);
1 #region 5.0 Ef 删除 的3中方式 2 private void btnDel_Click(object sender, EventArgs e) 3 { 4 //1.0 EF 推荐删除方式 - 先查,再删 5 ////1.1 先根据id查询 出 要删除的 对象(存入EF容器) 6 //BlogUser usr = db.BlogUsers.Where(u => u.Id == 45).FirstOrDefault(); 7 ////1.2 将实体对象删除(就是将 容器中的 代理对象的 State改成 Deleted) 8 //db.BlogUsers.Remove(usr); 9 ////1.3 将EF容器里所有的对象 根据 State 属性值,生成不同sql语句,更新到数据库 10 //db.SaveChanges(); 11 12 //2.0 使用 Attach + Remove Id = 2051 13 //BlogUser usr = new BlogUser() { Id = 2051 };//会根据指定主键删除(也只能根据指定id删除) 14 ////2.1 将对象 附加到 EF容器中 15 //db.BlogUsers.Attach(usr);//State=Unchanged 16 //db.BlogUsers.Remove(usr);//State=Deleted 17 //db.SaveChanges(); 18 19 //3.0 手动 设置删除 20 BlogUser usr = new BlogUser() { Id = 2052 }; 21 //3.1将对象加入 EF容器,并返回 代理对象里的跟踪器 22 DbEntityEntry entry = db.Entry(usr);//State=unchanged 23 //3.2将代理对象的状态 改成 删除状态 24 entry.State = EntityState.Deleted; 25 //3.3保存 26 db.SaveChanges(); 27 } 28 #endregion
1 //1.0 先按照条件查询 2 var list = db.BlogUsers.Where(u => u.IsDel == true).ToList(); 3 //2.0 遍历集合,将 要删除的 对象 的代理对象的State 设置为 Deleted 4 list.ForEach(u => db.BlogUsers.Remove(u)); 5 //3.0 执行更新 6 int resCount = db.SaveChanges(); 7 //4.0 获取受影响行数 8 MessageBox.Show("删除行数:" + resCount);
1 //1.EF推荐 - 先查,再改 2 //BlogArticle article = db.BlogArticles.Where(a => a.AId == 2).FirstOrDefault(); 3 //article.ATitle = "我爱广州小蛮腰2"; 4 //article.APlnum = 11; 5 //db.SaveChanges(); 6 7 //2.手动修改 8 //关闭EF的 为空 检查验证 9 db.Configuration.ValidateOnSaveEnabled = false; 10 //2.1 创建实体 11 BlogUser usrModel = new BlogUser() 12 { 13 Id = 28, 14 LoginName = "xiaobai1", 15 CnName = "小白" 16 }; 17 //2.2 加入到EF容器 18 DbEntityEntry entry = db.Entry(usrModel);//State=Detached ,EF容器部管理此状态的代理对象 19 //2.3 将代理对象状态 改为 Unchanged 以便接受 EF容器管理 20 entry.State = EntityState.Unchanged; 21 //2.4 指定 被修改的属性 对应的 IsModified 值,EF 会根据IsModified值判断是否要生成修改 的sql语句 22 entry.Property("LoginName").IsModified = true; 23 entry.Property("CnName").IsModified = true; 24 //2.5更新到数据库 25 db.SaveChanges(); 26 // 27 //db.Configuration.ValidateOnSaveEnabled = true;
引用类型不给值就为null
1 List<BlogUser> listUsers = new List<BlogUser>(); 2 //集合的 SQO 方法 定义在 System.Linq.Enumerable 类中,扩展到 IEnumerable<T>接口上 3 var listU = listUsers.Where(u => u.Id == 2); 4 5 //--------------------IQueryable 的SQO方法 最终目的是生成 SQL语句,其次才是执行sql语句,获取对象集合--------------- 6 ////EF 上下文里的 属性 都是 DBSet<T>类型,继承关系:DBSet<T> : DBQuery<T> : IQueryable<T> 7 //var listCates = db.BlogArticleCates; 8 ////EF的 SQO 方法 定义在 System.Linq.Queryable类中,扩展到 IQueryable<T>接口上 9 ////返回的是 实现了 IQueryable接口的 DBQuery类 的对象 10 //var listCates2 = db.BlogArticleCates.Where(c => c.IsDel == false); 11 12 ////排序的SQO方法,返回 IOrderedQueryable 接口:IQueryable接口,所以,也可以继续“链式编程” 13 //var listCates3 = db.BlogArticleCates.Where(c => c.IsDel == false).OrderBy(c => c.Id).ThenBy(c => c.Name.Length); 14 15 //1.0 EF默认 使用 延迟加载(按需加载) - 由DBQuery对象负责执行 16 //var listCate = db.BlogArticleCates.Where(c => c.IsDel == false).OrderBy(c => c.Id).ThenBy(c => c.Name.Length); 17 ////DBQuery只有被第一次访问的时候,才去 数据库查询数据,并 显示 18 //foreach (var cate in listCate) 19 //{ 20 // Console.WriteLine(cate.Id + "," + cate.Name); 21 //} 22 23 /*强调:凡是通过 EF 查询出来的 都是 代理类 对象 或 集合*/ 24 //2.0 EF 可以直接访问 外键属性(实体类的外键属性都是 virtual 属性,被代理对象重写,所以可以查询数据库) 25 var listCate = db.BlogArticleCates.Where(c => c.IsDel == false).OrderBy(c => c.Id).ThenBy(c => c.Name.Length); 26 // 当 访问 实体对象的 外键属性(BlogUser) 的时候,EF会自动根据 外键id(Author),查询 主键表(BlogUsers表) 27 // EF针对外键查询时,有优化:相同外键值 只查询一次!(比如 2个文章分类的作者都是 xiaobai,那么只需要查询一次 xiaobai) 28 foreach (var cate in listCate) 29 { 30 Console.WriteLine(cate.Id + "," + cate.Name + ",作者:" + cate.BlogUser.CnName); 31 }
1 //1.0 通过 Include 方法 生成 连接查询语句 (注意:Include只能跟在 DBSet属性后使用,然后再 调用SQO方法) 2 //var list = db.BlogArticleCates.Include("BlogUser").Include("BlogArticles").Where(c => c.IsDel == false); 3 //foreach (var item in list) 4 //{ 5 // Console.WriteLine(item.Id + "," + item.Name + ",作者:" + item.BlogUser.CnName+",文章数量:"+item.BlogArticles.Count); 6 //} 7 8 //2.0 通过 Select 方法 自动生成 连接查询语句,条件:在Select中使用到 外键属性(如:当前代码的 c.BlogUser.CnName),EF就会生成连接查询语句 9 var list2 = db.BlogArticleCates.Where(c => c.IsDel == false).Select(c => new { ID = c.Id, Name = c.Name, AuthorName = c.BlogUser.CnName }).ToList(); 10 list2.ForEach(c => Console.WriteLine(c.ToString()));
1 int resCount = db.Database.ExecuteSqlCommand("update BlogUser set LoginName=@lname where id=28", new SqlParameter("lname", "xiaobai")); 2 MessageBox.Show(resCount.ToString());