关于EntityFramework 更新数据记录时字段全部更新问题和不从数据库中获取直接更新记录
一、一直对这个比较疑惑感觉只修改一条数据记录的一个字段结果更新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 更新数据记录时字段全部更新问题和不从数据库中获取直接更新记录的更多相关文章
- mysql 从数据库中获取多条记录,二维展示数据
展示要求: 客户/日期 2017-10-16 1017-10-17 2017-10-18 客户1 客户2 数据库中数据: 解决办法: 1.新建一个实体类:客户名称.客户数据(A ...
- 当客户端提交更新数据请求时,是先写入edits,然后再写入内存的
http://blog.sina.com.cn/s/blog_6f83c7470101b7d3.html http://blog.csdn.net/slq1023/article/details/49 ...
- 使用python读取配置文件并从mysql数据库中获取数据进行传参(基于Httprunner)
最近在使用httprunner进行接口测试,在传参时,用到了三种方法:(1)从csv文件中获取:(2)在config中声名然后进行引用:(3)从函数中获取.在测试过程中,往往有些参数是需要从数据库中获 ...
- Oracle查询数据库中所有表的记录数
1.Oracle查询数据库中所有表的记录数,但是有可能不准建议用第二种方式进行查询 select t.table_name,t.num_rows from user_tables t 2.创建orac ...
- Django Form 实时从数据库中获取数据
修改 models.py 添加 class UserType(models.Model): caption = models.CharField(max_length=32) 执行命令,生成数据库 p ...
- Dynamics CRM 插件Plugin中获取和更新时间字段值的准确转换
前面两篇介绍了后台代码通过组织服务获取更新时间字段.窗体javascript通过Odata获取更新时间字段,最后篇来实验下在插件中的获取和更新时间字段是否需要时制的转化,为何说是最后篇呢,因为在CRM ...
- [SQL]查询某一个字段在某一段时期数据库中使用到的记录
有些时候我们常常须要哪里用到了一些表,又或者什么时候运行了某一个存储过程.整理出了在某段时期内数据库运行的sql查询.也能够查询到数据库中某些字段的存放处.非常好非常强大.希望能帮到大家~ SELEC ...
- PHP查询数据库中满足条件的记录条数(二种实现方法)
在需要输出网站用户注册数或者插入数据之前判断是否有重复记录时,就需要获取满足条件的MySQL查询的记录数目,接下来介绍两种查询统计方法,感兴趣的朋友可以了解下啊,或许对你有所帮助 在需要输出网 ...
- PHP如何实现在数据库随机获取几条记录
本文实例讲述了PHP实现在数据库百万条数据中随机获取20条记录的方法.PHP实例分享给大家供大家参考,具体如下: 为什么要写这个? 在去某个公司面试时,让写个算法出来,当时就蒙了,我开发过程中用到算法 ...
随机推荐
- shell /dev/null
/dev/null表示空设备,这里就是把日志记录到空设备里,就是不记录日志,Null 是一特殊指标值(或是一种物件参照 reference)表示这个指标并不指向任何的物件. 是一个特殊的文件,写入到它 ...
- __name__ 与 __main__解读
在python脚本中我们经常看到如下的代码: # hello.py def hello(): print("hello world!") def test(): hello() i ...
- Zookeeper 集群的安装及高可用性验证已完成!
安装包 kafka_2.12-0.10.2.0.tgz zookeeper-3.3.5.tar.gz Java 环境 Zookeeper 和 Kafka 的运行都需要 Java 环境,Kafka 默认 ...
- ARC080E
倒着考虑 每次拿出的第一个必须是奇数位置,第二个必须是偶数位置.每次删数都不能跨过已被删去的位置. 事实上只要开个堆维护一下区间就行了.但是众所周知我zz,所以我写的线段树 #include<i ...
- App加载主要流程
主要流程 Application OnCreate 加载第三方的sdk 加载自身的逻辑 发送远程数据请求 xxx.json 渲染界面 List
- CSS中的块级元素和行内元素
根据CSS规范的规定,每一个网页元素都有一个display属性,用于确定该元素的类型,每一个元素都有默认的display属性值,比如div元素,它的默认display属性值为“block”,成为“块级 ...
- 微信小程序のwxs语言
一.wxs介绍 wxs是微信小程序自身的脚本语言,用来过滤和计算.wxs可以通过文件可模块标签来定义 文件需要.wxs后缀文件 二.实例 <wxs module="test1" ...
- Allowance
Allowance 有n种数字,第i种数字值为\(v_i\),有\(b_i\)个,保证随i的增大而增大,且对于任意i有\(a_{i-1}|a_i\)(显然,\(i\in(1,n]\)),现求将它们划分 ...
- 在CMake中启用VS2017的C++17特性
VS2017的C++17特性默认并未开启,需要在编译参数中手动开启.找到项目的CMakeLists.txt,在查找编译器的代码后面加入如下内容即可. ") include(CheckCXXC ...
- WebService发送 方法
public String disableSaleOut(JSONObject jsonObject) throws ServiceException, MalformedURLException, ...