一、一直对这个比较疑惑感觉只修改一条数据记录的一个字段结果更新Savechages后跟踪生成sql竟然是全部被修改,感觉微软怎么这么傻,总觉得会有其它方式可以只更新部分字段,但一直没有找到相关设置,最近看DbContext相关内容发现是可以只更新部分字段,原来一直的操作方式是有问题下面粘代码详细说明。

1、首先看全部更新字段情况

    [TestMethod]
public void UpdateCustomer()
{ //Customer customer3 = new Customer();
//customer3.Id = 22;
//customer3.CustName = DateTime.Now.ToString("yyMMddHHmmssff");
//customer3.CustAddress = "北京25"; CustoemrRepository cuR = new CustoemrRepository();
Customer cuM = cuR.GetEntities(x => x.Id == ).FirstOrDefault();
cuM.CustAddress = "北京0614";
int row = cuR.UpdateModel(cuM);
}
   /// <summary>
/// 修改实体对象
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public int UpdateModel(TEntity model)
{
//if (unDbContext.Entry<TEntity>(model).State == System.Data.Entity.EntityState.Detached)
//{ // unDbContext.Entry(model).State = EntityState.Modified;
//} unDbContext.Entry(model).State = EntityState.Modified;
return unDbContext.SaveChanges();
}

这种修改方式生成的sql是

exec sp_executesql N'UPDATE [dbo].[Customer]
SET [CustName] = @, [CustCode] = NULL, [CustAddress] = @
WHERE ([Id] = @)
',N'@ nvarchar(max) ,@ nvarchar(max) ,@ int',@0=N'',@1=N'北京0614',@2=22

将Cutomer记录的全部字段更新了

如果将更新方式换做这样写

 /// <summary>
/// 修改实体对象
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public int UpdateModel(TEntity model)
{
if (unDbContext.Entry<TEntity>(model).State == System.Data.Entity.EntityState.Detached)
{
unDbContext.Entry(model).State = EntityState.Modified;
} return unDbContext.SaveChanges();
}

生成sql为

exec sp_executesql N'UPDATE [dbo].[Customer]
SET [CustAddress] = @
WHERE ([Id] = @)
',N'@ nvarchar(max) ,@ int',@0=N'北京0614',@1=22

可以看出这样只更新了 CustAddress 这个字段其它字段没有更新,这是因为 这句代码 unDbContext.Entry(model).State = EntityState.Modified; 没有执行,因为该数据记录是从数库中取出来的所以你修改记录相应字段后Entityframework会自动跟踪

修改字段 直接 unDbContext.SaveChanges();  就可以将修改记录保存到数据库,且只更新修改字段。 所以从数据库中取的数据记录“ unDbContext.Entry(model).State = EntityState.Modified;”这句不需要。

下面说一下这句
unDbContext.Entry(model).State = EntityState.Modified;
将其状态设为 EntityState.Modified 是针对要保存的实体对象不是从数据库中取出,而是在代码中 自己New的对象不是从数据库中取出来的,这时候需要
unDbContext.Entry(model).State = EntityState.Modified; 将其状态修改且Dbcontext为对它有相应修改处理,如果不设置对象将不在Dbcontext中会报错。

二、下面说一下怎样自己实例化的对象 不从数据库中取 然后更新数据记录,这样减少了一次数据库获取数据会提高相应效率,当然不太要求性能的系统中还是从数据库中取比较简单,下面做了一个简单实现大家感兴趣可以详细扩展。
   [TestMethod]
public void UpdateCustomer()
{ // 自己实例化要更新对象 省了访问数据库获取数据时间
Customer customer3 = new Customer();
customer3.Id = ;
customer3.CustAddress = "北京25";
List<string> listRmoveFiled = new List<string>();
listRmoveFiled = "CustCode,CustName".Split(',').ToList<string>(); CustoemrRepository cuR = new CustoemrRepository();
int row = cuR.UpdateModel(customer3,listRmoveFiled);
}
具体实现部分简单处理(大家可以写的风骚,精湛些)
   /// <summary>
/// 修改实体对象
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public int UpdateModel(TEntity model, List<string> listRemoveField = null)
{ // 排除不需更新的字段
foreach (string field in listRemoveField)
{
if (field != "Id")
unDbContext.Entry(model).Property(field).IsModified = false;
} if (unDbContext.Entry<TEntity>(model).State == System.Data.Entity.EntityState.Detached)
{
//将model追加到EF容器
unDbContext.Entry(model).State = EntityState.Modified;
}
return unDbContext.SaveChanges();
}
这样处理就可以省了从数据库中获取再修改,自己直接实例化更新部分字段就可以直接更新到数据库中。写到这里对这一块的整理也就结束了。
												

关于EntityFramework 更新数据记录时字段全部更新问题和不从数据库中获取直接更新记录的更多相关文章

  1. mysql 从数据库中获取多条记录,二维展示数据

    展示要求: 客户/日期 2017-10-16 1017-10-17 2017-10-18 客户1       客户2       数据库中数据: 解决办法: 1.新建一个实体类:客户名称.客户数据(A ...

  2. 当客户端提交更新数据请求时,是先写入edits,然后再写入内存的

    http://blog.sina.com.cn/s/blog_6f83c7470101b7d3.html http://blog.csdn.net/slq1023/article/details/49 ...

  3. 使用python读取配置文件并从mysql数据库中获取数据进行传参(基于Httprunner)

    最近在使用httprunner进行接口测试,在传参时,用到了三种方法:(1)从csv文件中获取:(2)在config中声名然后进行引用:(3)从函数中获取.在测试过程中,往往有些参数是需要从数据库中获 ...

  4. Oracle查询数据库中所有表的记录数

    1.Oracle查询数据库中所有表的记录数,但是有可能不准建议用第二种方式进行查询 select t.table_name,t.num_rows from user_tables t 2.创建orac ...

  5. Django Form 实时从数据库中获取数据

    修改 models.py 添加 class UserType(models.Model): caption = models.CharField(max_length=32) 执行命令,生成数据库 p ...

  6. Dynamics CRM 插件Plugin中获取和更新时间字段值的准确转换

    前面两篇介绍了后台代码通过组织服务获取更新时间字段.窗体javascript通过Odata获取更新时间字段,最后篇来实验下在插件中的获取和更新时间字段是否需要时制的转化,为何说是最后篇呢,因为在CRM ...

  7. [SQL]查询某一个字段在某一段时期数据库中使用到的记录

    有些时候我们常常须要哪里用到了一些表,又或者什么时候运行了某一个存储过程.整理出了在某段时期内数据库运行的sql查询.也能够查询到数据库中某些字段的存放处.非常好非常强大.希望能帮到大家~ SELEC ...

  8. PHP查询数据库中满足条件的记录条数(二种实现方法)

    在需要输出网站用户注册数或者插入数据之前判断是否有重复记录时,就需要获取满足条件的MySQL查询的记录数目,接下来介绍两种查询统计方法,感兴趣的朋友可以了解下啊,或许对你有所帮助     在需要输出网 ...

  9. PHP如何实现在数据库随机获取几条记录

    本文实例讲述了PHP实现在数据库百万条数据中随机获取20条记录的方法.PHP实例分享给大家供大家参考,具体如下: 为什么要写这个? 在去某个公司面试时,让写个算法出来,当时就蒙了,我开发过程中用到算法 ...

随机推荐

  1. docker stack利用secrets启动wordpress

    docker-compose文件 version: '3.1' services: web: image: wordpress ports: - : secrets: - my-pw environm ...

  2. 注解深入浅出之Retrofit中的注解(三)

    更多andorid高级架构进阶视频免费分享学习请点击:https://space.bilibili.com/474380680 Retrofit中的注解 @Query,@QueryMap,@Field ...

  3. JS数组中Array.of()方法的使用

    Array.of()方法的使用: Array.of()方法用于将一组数值转换为数组,举例: const a = Array.of(2,4,6,8); console.log(a); // [2,4,6 ...

  4. shell同时输出多行信息

  5. MYSQL-连续出现的数字

    编写一个 SQL 查询,查找所有至少连续出现三次的数字. +----+-----+| Id | Num |+----+-----+| 1 | 1 || 2 | 1 || 3 | 1 || 4 | 2 ...

  6. 锐浪报表 Grid++Report 一维码无法固定条形码打印宽度

    使用过 锐浪报表的 程序员 都知道,功能很强大,确实带来了很多便利,但今天发现一个问题,关于一维码的条形码无法固定宽度: 打印相差了0.07毫米,居然差别这么大, 打印出来的条码,要么太宽,要么太窄 ...

  7. IntelliJ IDEA2016.1 + maven 创建java web 项目[转]

    最近开始使用idea 来写java项目了,这个很流行,相比Eclipse方便了很多.功能多了,相对应的使用的复杂度也较高了,因为网上很多的使用和创建项目的简单教程,都是基于老版本的,每个新版本都有不一 ...

  8. Attribute 实现Aop

    1.先定义一个 拦截属性 AopAttribute using System; using System.Collections.Generic; using System.Linq; using S ...

  9. 电脑U盘启动制作

    1.用老毛桃.大白菜制作U盘驱动时,不要直接默认一键制作.不然安装的系统会植入第三方的软件的.一定要进行个性化设置中取消赞助商.

  10. 第一次安装hadoop记录

    需求是:安装hadoop连接远程hadoop文件系统.JDK和hadoop需要与集群版本一致 首先去官网下载hadoop http://archive.apache.org/dist/hadoop/c ...