【Entity Framework】EF中的增删改查

简介: 【Entity Framework】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;


四、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();

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


  • ObjectSet的AddObject方法。
  • ObjectContext的AddObject方法
  • EntityCollection的Add方法。对于实体框架生成的实体和代理对象,在附加主体对象时也会将添加的实体附加到上下文中,调用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
}; 

2.添加到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. 更新全部字段
db.Entry(userInfonew).State = EntityState.Modified;
  1. 更新部分字段
db.Entry(userInfonew).Property(x => x.Email).IsModified = true;
• 1
  1. 更新到数据库
db.SaveChanges();

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

5.2 先查询实体再更新

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

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

  1. 查询实体后不使用查询的实体,手动创建实体
 var query = await (from a in db.MesMachineConfig
                    join c in db.Site_LinePosition
                    on 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 rightRow
                    from rw in rightRow.DefaultIfEmpty()
                    where a.Enable == "Y" && a.Size == dghkrOneReelNumManagerParamsSettingsDto.Size
                    select 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();
var

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();
目录
相关文章
|
21天前
|
SQL 关系型数据库 MySQL
学成在线笔记+踩坑(3)——【内容模块】课程分类查询、课程增改删、课程计划增删改查,统一异常处理+JSR303校验
课程分类查询、课程新增、统一异常处理、统一封装结果类、JSR303校验、修改课程、查询课程计划、新增/修改课程计划
学成在线笔记+踩坑(3)——【内容模块】课程分类查询、课程增改删、课程计划增删改查,统一异常处理+JSR303校验
|
8天前
|
SQL 关系型数据库 MySQL
ThinkPHP6 连接使用数据库,增删改查,find,select,save,insert,insertAll,insertGetId,delete,update方法的用法
本文介绍了在ThinkPHP6框架中如何连接和使用数据库进行增删改查操作。内容包括配置数据库连接信息、使用Db类进行原生MySQL查询、find方法查询单个数据、select方法查询数据集、save方法添加数据、insertAll方法批量添加数据、insertGetId方法添加数据并返回自增主键、delete方法删除数据和update方法更新数据。此外,还说明了如何通过数据库配置文件进行数据库连接信息的配置,并强调了在使用Db类时需要先将其引入。
ThinkPHP6 连接使用数据库,增删改查,find,select,save,insert,insertAll,insertGetId,delete,update方法的用法
|
2月前
|
SQL 数据库连接 API
ThinkPHP6实现增删改查接口
ThinkPHP6实现增删改查接口
33 1
|
2月前
|
XML 数据库 数据格式
Spring5入门到实战------14、完全注解开发形式 ----JdbcTemplate操作数据库(增删改查、批量增删改)。具体代码+讲解 【终结篇】
这篇文章是Spring5框架的实战教程的终结篇,介绍了如何使用注解而非XML配置文件来实现JdbcTemplate的数据库操作,包括增删改查和批量操作,通过创建配置类来注入数据库连接池和JdbcTemplate对象,并展示了完全注解开发形式的项目结构和代码实现。
Spring5入门到实战------14、完全注解开发形式 ----JdbcTemplate操作数据库(增删改查、批量增删改)。具体代码+讲解 【终结篇】
|
2月前
|
SQL XML Java
Spring5入门到实战------12、使用JdbcTemplate操作数据库(增删改查)。具体代码+讲解 【上篇】
这篇文章是Spring5框架的实战教程,详细讲解了如何使用JdbcTemplate进行数据库的增删改查操作,包括在项目中引入依赖、配置数据库连接池、创建实体类、定义DAO接口及其实现,并提供了具体的代码示例和测试结果,最后还提供了完整的XML配置文件和测试代码。
Spring5入门到实战------12、使用JdbcTemplate操作数据库(增删改查)。具体代码+讲解 【上篇】
|
2月前
|
数据库 C# 开发者
WPF开发者必读:揭秘ADO.NET与Entity Framework数据库交互秘籍,轻松实现企业级应用!
【8月更文挑战第31天】在现代软件开发中,WPF 与数据库的交互对于构建企业级应用至关重要。本文介绍了如何利用 ADO.NET 和 Entity Framework 在 WPF 应用中访问和操作数据库。ADO.NET 是 .NET Framework 中用于访问各类数据库(如 SQL Server、MySQL 等)的类库;Entity Framework 则是一种 ORM 框架,支持面向对象的数据操作。文章通过示例展示了如何在 WPF 应用中集成这两种技术,提高开发效率。
41 0
|
2月前
|
Java 前端开发 Spring
技术融合新潮流!Vaadin携手Spring Boot、React、Angular,引领Web开发变革,你准备好了吗?
【8月更文挑战第31天】本文探讨了Vaadin与Spring Boot、React及Angular等主流技术栈的最佳融合实践。Vaadin作为现代Java Web框架,与其他技术栈结合能更好地满足复杂应用需求。文中通过示例代码展示了如何在Spring Boot项目中集成Vaadin,以及如何在Vaadin项目中使用React和Angular组件,充分发挥各技术栈的优势,提升开发效率和用户体验。开发者可根据具体需求选择合适的技术组合。
36 0
|
2月前
|
SQL 关系型数据库 数据库连接
Entity Framework Core 入门教程来袭!快速上手强大的 ORM 工具,开启高效数据库开发之旅!
【8月更文挑战第31天】Entity Framework Core(EF Core)是一个轻量且可扩展的对象关系映射(ORM)框架,允许开发者使用 .NET 语言操作数据库而无需直接编写 SQL 语句。本教程涵盖 EF Core 的安装、数据库上下文创建、数据库连接配置及常见数据库操作(如添加、查询、更新和删除),并介绍如何利用数据库迁移功能安全地更改数据库结构。通过本教程,你可以快速掌握 EF Core 的基本用法,提高开发效率。
38 0
|
2月前
|
开发工具 数据安全/隐私保护 索引
LDAP学习笔记之二:389-DS(RHDS) 增删改查基本操作
LDAP学习笔记之二:389-DS(RHDS) 增删改查基本操作
|
2月前
|
关系型数据库 MySQL 数据库
MySQL数据库的增删改查
MySQL数据库的增删改查
14 0
下一篇
无影云桌面