Entity Framework使用EntityState和Attach来保存数据变化以及更新实体的个别字段

在使用Entity Framework作为ORM来存取数据的过程中,最常规的操作就是对数据对象的更新。本文将会包含如何Attach Entity到一个数据Context中,以及如何使用EntityState字段状态来保存数据变化。

文本参考了如下两篇文章:

https://msdn.microsoft.com/en-us/data/jj592676

https://stackoverflow.com/questions/30987806/dbset-attachentity-vs-dbcontext-entryentity-state-entitystate-modified

当要做数据更新时,我们通常会使用如下代码:

1 context.Entity(entity).State = EntityState.Modified;

2 context.SaveChanges();

context.Entity(entity).State = EntityState.Modified; 这句代码不仅会将entity attaching到当前的context中,而且还会告诉context这个entity已经发生了变化。当执行savechanges()时,EF会使用update语句将entity中所有的字段全部更新。

上面的这种方式虽然方便,但是在某些时候也会带来效率上的浪费。如果我们只是想更新其中的某个或者某些字段而不是全部字段的时候,使用这种方式就不必要了。那么该如何操作,才能让Entity Framework精确的保存我们想要变更的字段呢?我们可以使用Dbset.Attach(entity)。

Dbset.Attach(entity)只是会将entity attach到context中,而不会告诉context这个实体已经发生修改。所以如果你只是attach entity而之后不做任何处理的话,savechanges()操作将不会有任何变化。所以它和context.Entity(entity).State = EntityState.Unchanged是相同的。要保存个别字段,需要将entity更改之后再调用savechanges方法。请参见下面的代码样例。

代码样例:

下面使我们定义的实体以及它们的Context:

 1 public class Department
 2 {
 3 public int Id {get;set;}
 4 public string Name {get;set;}
 5 public DateTime CreateTime {get;set;}
 6
 7 public int DepLeadID { get; set; }
 8
 9 [ForeignKey("DepLeadID")]
10 public DepLead Lead {get;set;}
11 }
1 public class DepLead
2 {
3 public int Id {get;set;}
4 public string name {get;set;}
5 public int age {get;set;}
6 }
 1 public class Context : DbContext
 2     {
 3         public Context() : base("XXX")
 4         {
 5         }
 6         public DbSet<Department> Departments { get; set; }
 7         public DbSet<DepLead> DepLeads { get; set; }
 8
 9         protected override void OnModelCreating(DbModelBuilder modelBuilder)
10         {
11             modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
12         }
13
14     }

如果我们使用如下方式更新数据:

context.Entity(someDepartment).State = EntityState.Modified;
context.SaveChanges();

那么相当于执行如下SQL

UPDATE department
SET Name = ‘xxx‘,CreateTime = ‘XXX‘, DepLeadID = ‘XXX‘
where Id = ‘1000‘; -- the id of someDepartment

上面的这种方式,不会自动的检查字段是否变化,而是把所有的字段全部按照someDepartment中的值进行更新,即使没有任何变化。

而另外一种Attach的方式在更新上就会更加灵活。

context.Departments.Attach(someDepartment);
someDepartment.Name = ‘XXX‘;
context.SaveChanges();

以上片段会执行下面语句:

UPDATE department
set Name = ‘XXX‘
where Id = ‘1000‘

假如你想指定实体someDepartment中哪些字段是已经更改的状态,可以按如下代码:

context.Departments.Attach(someDepartment);
context.Entry(someDepartment).Property("Name").IsModified = true;
context.SaveChanges();

这样它也会像上面的SQL那样将Name字段更新。

原文地址:https://www.cnblogs.com/Jason-blogs/p/8722871.html

时间: 2024-10-07 05:26:29

Entity Framework使用EntityState和Attach来保存数据变化以及更新实体的个别字段的相关文章

《Entity Framework 6 Recipes》中文翻译系列 目录篇 -持续更新

为了方便大家的阅读和学习,也是响应网友的建议,在这里为这个系列做一个目录.在目录开始这前,我先来回答之前遇到的几个问题. 1.为什么要学习EF? 这个问题很简单,项目需要.这不像学校,没人强迫你学习! 我学习EF的原因主要是: a.EF是微软推荐的数据库访问技术: b.能提高我的开发效率,我不喜欢写那密密麻麻的SQL: c.比我写的SQL更合理,更快.目前EF生成的SQL的质量已经很高了.你比较熟悉SQL的话,那它在速度上肯定比不上你,新手的话就别跟我争快慢了,能写一像样的SQL就不错了.至少我

entity framework 6 我写了一个公用数据类

public class BaseDAL { string strConn = ""; public BaseDAL(string connString) { strConn = connString; } #region 通用增删改查 #region 非原始sql语句方式 /// <summary> /// 新增 /// </summary> /// <param name="entity">实体</param> /

《Entity Framework 6 Recipes》翻译系列(2) -----第一章 开始使用实体框架之使用介绍 (转)

Visual Studio 我们在Windows平台上开发应用程序使用的工具主要是Visual Studio.这个集成开发环境已经演化了很多年,从一个简单的C++编辑器和编译器到一个高度集成.支持软件开发整个生命周期的多语言环境. Visual Studio以及它发布的工具和服务提供了:设计.开发.单元测试.调试.软件配置和管理.构建管理和持续集成等等.很少有开发人员因为还没有使用它而担心(注:作者应该是表达不用担心VS的能力),Visual Studio是一个完整的工具集.Visual Stu

《Entity Framework 6 Recipes》翻译系列 (1) -----第一章 开始使用实体框架之历史和框架简述 (转)

微软的Entity Framework 受到越来越多人的关注和使用,Entity Framework7.0版本也即将发行.虽然已经开源,可遗憾的是,国内没有关于它的书籍,更不用说好书了,可能是因为EF版本更新太快,没人愿意去花时间翻译国外关于EF的书籍.使用Entity Framework开发已经有3年多了,但用得很肤浅,最近想深入学习,只好找来英文书<Entity Framework 6 Recipes>第二版,慢慢啃.首先需要说明的是,我英文不好,只是为了学习EF.把学习的过程写成博客,一

《Entity Framework 6 Recipes》翻译系列 2 -----第一章 开始使用实体框架2

Visual Studio 我们在Windows平台上开发应用程序使用的工具主要是Visual Studio.这个集成开发环境已经演化了很多年,从一个简单的C++编辑器和编译器到一个高度集成.支持软件开发整个生命周期的多语言环境. Visual Studio以及它发布的工具和服务提供了:设计.开发.单元测试.调试.软件配置和管理.构建管理和持续集成等等.很少有开发人员因为还没有使用它而担心(注:作者应该是表达不用担心VS的能力),Visual Studio是一个完整的工具集.Visual Stu

Entity Framework 使用注意:Where查询条件中用到的关联实体不需要Include

来自博客园开发团队开发前线最新消息: 在Entity Framework中,如果实体A关联了实体B,你想在加载实体A的同时加载实体B.通常做法是在LINQ查询中使用Include().但是,如果你在查询条件中用到了实体B,EF会自动加载实体B,这时Include不仅是多余的,而且还会增加额外的LEFT OUTER JOIN查询,影响性能. 请看我们在博问开发中遭遇这个问题时的一段代码: //For q.cnblogs.com public class QuestionService { priv

Entity Framework(三):使用特性(数据注解)创建表结构

一.理解Code First及其约定和配置 传统设计应用的方式都是由下而上的,即我们习惯优先考虑数据库,然后使用这个以数据为中心的方法在数据之上构建应用程序.这种方法非常适合于数据密集的应用或者数据库很可能包含多个应用使用的业务逻辑的应用.对于这种应用,如果要使用EF的话,我们必须使用Database First方式. 设计应用的另一种方法就是以领域为中心的方式(领域驱动设计DDD).DDD是一种由上而下的方式,我们通过从实现应用所需要的领域模型和实体的角度思考,从而开始设计应用.数据库很少用来

Entity Framework Extended Library (EF扩展类库,支持批量更新、删除、合并多个查询等)

今天乍一看,园子里居然没有关于这个类库的文章,实在是意外毕竟已经有很多介绍EF使用的文章了. E文好的可以直接看https://github.com/loresoft/EntityFramework.Extended 也可以在nuget上直接安装这个包,它的说明有点过时了,最新版本已经改用对IQueryable<T>的扩展,而不是DbSet<T>(已经标记为弃用),所以跟我一样有隔离癖好的就可以大胆使用了.下面介绍如何批量删除.更新.查询. 批量删除 本来我们需要这样删除 ? //

Entity Framework 中的Code First 中引入数据库函数

1,在项目中添加CodeFirstStoreFunctions包: Install-Package EntityFramework.CodeFirstStoreFunctions 2,注册注册函数,FunctionsConvention第二个参数为函数定义所在的类 protected override void OnModelCreating(DbModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); //注册函数 mod