【Entity Framework】EF中的增删改查

【Entity Framework】EF中的增删改查

文章目录

  • 【Entity Framework】EF中的增删改查
    • 一、概述
    • 二、DbContext数据上下文
    • 三、EntityState五个状态值
    • 四、EF添加数据
      • 4.1 EF Add方式
      • 4.2 EF 通过改变对象的状态为 Added
      • 4.3 调用方sql
      • 4.4 调用存储过程
    • 五、EF修改数据
      • 5.1 不查询数据库,主键必须赋值
      • 5.2 先查询实体再更新
    • 六、EF删除数据
      • 6.1 先查询数据,再根据查询的对象 ,删除对象
      • 6.2 自己创建对象,后附件,然后执行删除
      • 6.3 自己创建对象,然后放入EF容器,然后删除

在这里插入图片描述

一、概述

Entity Framework是一个O/R Mapping的实例框架,前面的博文介绍了Entity Framework的知识体系,本文将介绍EF基本使用,Entity Framework操作数据库,完成基本的增删改查。

二、DbContext数据上下文

DbContextEntity Framework中的一个核心的类,它充当了应用程序和数据库之间的桥梁。DbContext主要负责以下任务:

  • 定义数据库上下文:DbContext包含与数据库连接相关的信息,例如数据库提供程序、连接字符串等。它也可以被视为一个数据库的代理,应用程序通过它来访问数据库。
  • 定义实体映射:DbContext包含一个或多个DbSet,每个DbSet表示一个实体类型(通常是C#类)和数据库中的一个表。DbContext将实体类和数据库表之间的映射关系定义在一个模型中,这样就可以方便地进行数据的查询和操作。
  • 执行SQL查询:当使用Entity Framework进行数据查询时,DbContext会将LINQ查询转换为SQL查询,并发送到数据库执行。
  • 管理事务:DbContext提供了一个默认的事务管理器,用于管理数据库事务。在执行SaveChanges()方法时,事务自动提交或回滚。
  • 更改跟踪:DbContext跟踪每个实体的状态,包括新增(added)、修改(modified)和删除(deleted)状态。这使得在执行SaveChanges()方法时,Entity Framework能够生成正确的SQL语句来更新数据库。

三、EntityState五个状态值

SavaChanged()用于提交数据,db.SaveChanged() 返回值是数据库中有几条数据被影响,所以你可以用db.SaveChanged()>0来判断是否成功插入,修改,删除数据。

当执行SaveChanged()方法执行期间,会根据EntityState的值,决定是去新增(Added)、修改(Modified)、删除(Deleted)。来执行操作。

  db.Entry(userinfo).State = EntityState.Added;
序号字段说明
1Added4该对象是已添加到对象上下文的新对象,但尚未调用SaveChanges()方法。在保持更改后,对象状态更改为Unchanged。处于Added状态的对象在ObjectStateEntity中没有原始值。
2Deleted8已从对象上下文中删除该对象,在保存更改后,对象状态更改为Detached
3Detached1该对象在但未被跟踪。实体在创建之后且添加到对象上下文之前处于此状态。通过调用Detach(Object)方法从上下文中移除实体后,或者使用NoTrackingMergeOption加载实体后,该实体也会处于此状态。没有与处于ObjectStateEntry状态对象关联的Detached实体。
4Modified16对象上的一个标量属性已修改,但尚未调用SaveChanges()方法。在没有更改跟踪代理的POCO实体中,如果调用Modified方法,则已修改属性的状态将更改为DetechChanges()。保存更改后,对象状态更改为Unchanged
5Unchanged2自附加到上下文中后,或自上次调用SaveChanges()方法后,该对象尚未修改。

四、EF添加数据

要在数据源中插入数据时,必须创建实体类型的实例,并将该对象添加到对象上下文。 若要将新对象保存到数据源中,必须先设置不支持 null 值的所有属性。 使用实体框架 生成的类时,考虑使用实体类型的静态 Create对象名称 方法创建实体类型的新实例。 实体数据模型 工具生成实体类型时,会在每个类中包含此方法。 此创建方法用于创建对象的实例并设置此类的不能为 null 的所有属性。 此方法对于在 CSDL 文件中已应用 Nullable="false" 特性的每个属性都包含一个参数。

4.1 EF Add方式

RbacDBEntities db = new RbacDBEntities();
Role r1 = new Role()
{Name = “方式1”,Remark = “备注1”
};
db.Roles.Add(r1);
db.SaveChanges();

4.2 EF 通过改变对象的状态为 Added

Role r2 = new Role()
{Name = “方式2”,Remark = “备注2”
};
db.Entry(r2).State = System.Data.Entity.EntityState.Added;
db.SaveChanges();

4.3 调用方sql

string sql = @“insert into roles values(‘方式3’,‘备注3’)”;
db.Database.ExecuteSqlCommand(sql);
db.SaveChanges();

4.4 调用存储过程

db.cp_insert_role(“方法4”, “备注4”);
Console.Read();

可以使用以下方法之一将新对象添加到对象上下文中:

  • ObjectSetAddObject方法。
  • ObjectContextAddObject方法
  • EntityCollectionAdd方法。对于实体框架生成的实体和代理对象,在附加主体对象时也会将添加的实体附加到上下文中,调用DetectChanges方法时将附件POCO实体。

在添加新对象时需要考虑下列注意事项:

  • 调用 SaveChanges 之前,实体框架 会为每个新对象生成一个临时的键值。 调用 SaveChanges 后,该键值会被插入新行时数据源所指定的标识值所取代。
  • 如果数据源未生成实体的键值,应指定一个唯一值。 如果两个对象具有相同的用户指定键值,则在调用 SaveChanges 时会发生InvalidOperationException。如果发生此问题,应指定唯一值并重试该操作。

五、EF修改数据

5.1 不查询数据库,主键必须赋值

为避免先查询数据库,可以直接将被修改的实体对象,添加到EF中管理,并手动设置其为未修改状态(Unchanged),同时设置被修改的实体对象的包装类对象对应属性为修改状态。

优点: 修改前不需要查询数据库

  1. 创建修改的实体对象
UserInfoes userInfonew = new UserInfoes()
{UserId=userInfo.UserId,Email = userInfo.Email,FirstName = userInfo.FirstName,LastName = userInfo.LastName,LastUpdateBy = GetCurrentUserGuid(),LastUpdate = DateTime.Now
}; 
  1. 添加到EF管理容器中

如果使用Entry附加实体对象到数据容器中,则需要手动设置实体包装类的对象的状态为Unchanged,或使用Attach(Attach方法:将给定实体以 System.Data.EntityState.Unchanged 状态附加到上下文中从解释可以看出Attach方法主要目的就是把一个没有被dbContext跟踪的对象附加到dbCotext中使其被dbContext跟踪)。

db.Entry(userInfonew).State = System.Data.Entity.EntityState.Unchanged;

或者

db.UserInfoes.Attach(userInfonew);
  1. 更新字段

    1. 更新全部字段
     db.Entry(userInfonew).State = EntityState.Modified;
    
    1. 更新部分字段
    db.Entry(userInfonew).Property(x => x.Email).IsModified = true;
    
  2. 更新到数据库

db.SaveChanges();

特别提醒:主键必须赋值,如果不赋值,会报错“Store update,insert or delete statement affected an unexpected number of rows(0)”

5.2 先查询实体再更新

  1. 查询实体后更新数据库

    1. 先查询要修改的原数据(注意此处不要加AsNoTracking(),加了无法更新)
    var userInfoes= db.UserInfoes.Where(a => a.UserId== model.UserId).FirstOrDefault(); 
    
    1. 更新字段的值
    userInfoes.LastUpdateBy = GetCurrentUserGuid();
    userInfoes.LastUpdate = DateTime.Now;
    
    1. 更新到数据库
    db.SaveChanges(); 
    

    注意:EF查询出来的实体是无法更新主键的值

  2. 查询实体后不使用查询的实体,手动创建实体

 var query = await (from a in db.MesMachineConfigjoin c in db.Site_LinePositionon new {A = a.LineNum,B = a.MCPosition} equals new {A= c.LineNum,B=c.MCPosition}join b in db.DGHKROneReelNumManagerParamsSettings on a.MachineNum equals b.MachineNum into rightRowfrom rw in rightRow.DefaultIfEmpty()where a.Enable == "Y" && a.Size == dghkrOneReelNumManagerParamsSettingsDto.Sizeselect new {a,rw}

Attach的时候会报如下错误:因为相同类型的其他实体已具有相同的主键值。在使用 “Attach” 方法或者将实体的状态设置为 “Unchanged” 或 “Modified” 时如果图形中的任何实体具有冲突键值,则可能会发生上述行为。

六、EF删除数据

6.1 先查询数据,再根据查询的对象 ,删除对象

var delSysUser = accountContext.SysUsers.FirstOrDefault(m.m.Id==userId)
if(delSysUser==null)
{accountContext.SysUsers.Remove(delSysUser);
}
var i = accountContext.SaveChanges();

6.2 自己创建对象,后附件,然后执行删除

SysUser delSysUser = new SysUser(){Id = delId};
accountContext.SysUsers.Attach(delSysUser);
accountContext.SysUsers.Remove(delSysUser);
var i = accountContext.SaveChanges();

6.3 自己创建对象,然后放入EF容器,然后删除

SysUser delSysUser=new SysUser(){Id = delId};
DbEntityEntry<SysUser> entityEntry = accountContext.Entry(delSysUser);
entityEntry.State = EntityState.Deleted;
var i = accountContext.SaveChanges();

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/586398.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何启用远程访问?

在当今信息化的社会中&#xff0c;远程访问已成为许多企业和个人不可或缺的工具。通过远程访问&#xff0c;用户可以在任何时间、地点轻松连接到他们的数据和应用程序&#xff0c;提高工作效率&#xff0c;增加便利性。本文将探讨如何启用远程访问&#xff0c;以及天联组网在解…

【Java常用的API】JDK8相关时间类

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【Java】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收藏 …

树与二叉树的应用试题

01&#xff0e;在有n个叶结点的哈夫曼树中&#xff0c;非叶结点的总数是( A ). A. n-1 B. n C. 2n-1 D.2n解析&#xff1a;哈夫曼树中只有度为0和2的结点&#xff0c;在非空二…

站群CMS系统

站群CMS系统是一种用于批量建立和管理网站的内容管理系统&#xff0c;它能够帮助用户快速创建大量的网站&#xff0c;并实现对这些网站的集中管理。以下是三个在使用广泛的站群CMS系统&#xff0c;它们各具特色&#xff0c;可以满足不同用户的需求。 1. Z-BlogPHP Z-BlogPHP是…

(vue)el-checkbox-group怎么指定列数整齐显示

(vue)el-checkbox-group怎么指定列数整齐显示 <template><el-checkboxv-if"ziduanOptions.length ! 0"v-model"checkAll":indeterminate"isIndeterminate"change"handleCheckAllChange">全选</el-checkbox><div …

【Mars3d绘制完成后设置离地面的实体高度】graphicLayer.startDraw绘制带高度的实体

实现效果&#xff1a; 相关需求场景&#xff1a; 绘制之后可以在success中通过graphic可以拿到所点击的点的位置&#xff0c;然后重新生成一个graphic添加到地图上&#xff0c;重新生成的面在初始化的时候可以指定想要的高度 相关实现代码&#xff1a; // 开始绘制多边形 exp…

154 Linux C++ 通讯架构实战9 ,信号功能添加,信号使用sa_sigaction 回调,子进程添加,文件IO详谈,守护进程添加

初始化信号 使用neg_init_signals(); 在nginx.cxx中的位置如下 //(3)一些必须事先准备好的资源&#xff0c;先初始化ngx_log_init(); //日志初始化(创建/打开日志文件)&#xff0c;这个需要配置项&#xff0c;所以必须放配置文件载入的后边&#xff1b;//(4)一些初…

面向对象特征三:多态性

一千个读者眼中有一千个哈姆雷特。 多态的形式和体现 对象的多态性 多态性&#xff0c;是面向对象中最重要的概念&#xff0c;在Java中的体现&#xff1a;对象的多态性&#xff1a;父类的引用指向子类的对象 格式&#xff1a;&#xff08;父类类型&#xff1a;指子类继承的父…

怎么对电脑屏幕进行远程控制

远程控制是指管理人员在异地通过计算机网络异地拨号或双方都接入Internet等手段&#xff0c;连通需被控制的计算机&#xff0c;将被控计算机的桌面环境显示到自己的计算机上&#xff0c;通过本地计算机对远方计算机进行配置、软件安装程序、修改等工作。 远程控制并不仅仅局限…

kettle使用MD5加密增量获取接口数据

kettle使用MD5加密增量获取接口数据 场景介绍&#xff1a; 使用JavaScript组件进行MD5加密得到Http header&#xff0c;调用API接口增量获取接口数据&#xff0c;使用json input组件解析数据入库 案例适用范围&#xff1a; MD5加密可参考、增量过程可参考、调用API接口获取…

docker容器之etcd安装

一、etcd介绍 1、etcd是什么 etcd是CoreOS团队于2013年6月发起的开源项目&#xff0c;它的目标是构建一个高可用的分布式键值(key-value)数据库。 2、etcd特点 简单的接口&#xff0c;通过标准的HTTP API进行调用&#xff0c;也可以使用官方提供的 etcdctl 操作存储的数据。…

Adaboost集成学习 | Matlab实现基于LSTM-Adaboost长短期记忆神经网络结合Adaboost集成学习时间序列预测(股票价格预测)

目录 效果一览基本介绍模型设计程序设计参考资料效果一览 基本介绍 Adaboost集成学习 | Matlab实现基于LSTM-Adaboost长短期记忆神经网络结合Adaboost集成学习时间序列预测(股票价格预测) 模型设计 股票价格预测是一个具有挑战性的时间序列预测问题,可以使用深度学习模型如…