.net core更新部分字段方法总结

efcore和.netcore更新部分字段,或更新部分列数据,update操作网上说的千奇百怪,有的根本不能执行,所以在此,进行了总结,欢迎大家参考

一、利用TryUpdateModelAsync

此方法首先查询出实体数据,然后根据lambda表达式中的字段进行更新对应的实体字段,注意lambda表达式,都为这样的参数格式o=>o.x1,o=>o.x2而不是o=>o.x1,o.x2

二、查询出实体,然后将表单form中的实体与查询出来的实体对应修改

三、字段绑定更新部分,将所有字段值读出来,然后在html中将不更新的字段设置为readonly,这样用户只能操作需要更新的字段值,但这也有一个问题,如果用户懂计算机,将实体在html中的readonly去掉,会导致后台更新数据 的同时会把值更新

view视图文件

假设只更新content字段数据

四、利用属性设置更新部分字段,适用于更新字段少的情况,比如实体总共有10个字段,仅更新两个或一个字段的情况下,可以设置如下 :比如只更新了username字段

但如果需要更新的列多的话,会照样写成很多类似语句:

当然这样的语句可以用循环的方式实现,将需要更新的字段封装起来,然后通过循环遍历设置为true,以下代码可以参考

 

五、如果更新字段较多,上面的方法都要写一堆需要更新字段的代码,假如有10个字段,更新9个,仅有一个字段不更新,那么,可以用以下方法,此方法适用总字段较多,但更新的字段较少的情况,和上面的正好相反。具体如下:

注意:加了Attach在SaveChanges()前面一定不要再加dbContext.Update(user);加上此句会出错,导致上面的设置状态无效,会全部更新,所以一定不要加。

六、使用原生SQL执行更新操作

dbContext.Database.ExecuteSqlRaw("sql语句",参数1值, 参数2值,...);

 警告

始终对原始 SQL 查询使用参数化

向原始 SQL 查询引入任何用户提供的值时,必须注意防范 SQL 注入攻击。 除了验证确保此类值不包含无效字符,请始终使用会将值与 SQL 文本分开发送的参数化处理。

具体而言,如果连接和内插的字符串 ($"") 带有用户提供的未经验证的值,则切勿将其传递到 FromSqlRaw 或 ExecuteSqlRaw。 通过 FromSqlInterpolated 和 ExecuteSqlInterpolated 方法,可采用一种能抵御 SQL 注入攻击的方式使用字符串内插语法。一般这种方法用于内部确定的更新操作。比如将某个字段更新为某个值等。

以上方法必须保证参数值是经过处理的,否则不建议用$""这样的形式。下面的两个方法进行参数化防止sql注入攻击:

  • 第一种简写:

  • 第二种参数写法:

这里是mysql用 MySqlParameter,sql用SqlParameter,注意对应关系否则出错,代码如下:

上面使用的参数化赋值,参数可与字段名不同,可以参考对比。

FromSqlRaw只用作查询。

params object[] parameters或params object[] args作为方法参数时,指明该参数为可变长度和类型参数,比如“abc",1,true可传入。

 

前面几种方法根据具体情况使用即可。

关于过度发布:

经常见类似这样的[bind("")] User user,为什么要绑定对应字段呢,主要是为了防止过度发布,比如User实体中有3个字段,分别 为id,username,userpassword,在进行更新Edit操作时,虽然表单里对应的只id,name两个input,但下面的代码user对象里是3个字段,黑客会利用工具将userpassword字段什传入了,导致更新时把密码也修改了!

微软官方实例如下图:

防止以上过度发布可以使用Bind属性来绑定需要更新的字段,其它字段即可传送过来也会清空,但这样在更新数据时不能直接dbcontext.update(user)然后进行savechanges()提交。只能查询到的user实体,再将参数中user赋值到需要更新的字段,当然还有更好的办法是使用上面提到的,

将需要更新的字段更新,这种方法不需要进行查询,直接使用的user实体。

 

 

参考资料:

EntityState的5个状态解释:

成员名称 说明
Detached 对象存在,但没有被跟踪。 在创建实体之后、但将其添加到对象上下文之前,该实体处于此状态。 An entity is also in this state after it has been removed from the context by calling the Detach method or if it is loaded by using a NoTrackingMergeOption. 没有 ObjectStateEntry 实例与状态为 Detached 的对象关联。
Unchanged 自对象附加到上下文中后,或自上次调用 SaveChanges 方法后,此对象尚未经过修改。
Added 对象为新对象,并且已添加到对象上下文,但尚未调用 SaveChanges 方法。 在保存更改后,对象状态将更改为 Unchanged。 状态为 Added 的对象在 ObjectStateEntry 中没有原始值。
Deleted 对象已从对象上下文中删除。 在保存更改后,对象状态将更改为 Detached。
Modified 对象上的一个标量属性已更改,但尚未调用 SaveChanges 方法。 在不带更改跟踪代理的 POCO 实体中,调用 DetectChanges 方法时,已修改属性的状态将更改为 Modified。 在保存更改后,对象状态将更改为 Unchanged。

https://docs.microsoft.com/zh-cn/dotnet/api/microsoft.entityframeworkcore.entitystate?view=efcore-5.0#Microsoft_EntityFrameworkCore_EntityState_Modified

上下文正在跟踪实体的状态。

C#

继承

EntityState

字段

字段
Added 4 实体正在由上下文跟踪,但数据库中尚不存在。
Deleted 2 实体正在由上下文跟踪,并存在于数据库中。 已将其标记为从数据库中删除。
Detached 0 上下文未跟踪该实体。
Modified 3 实体正在由上下文跟踪,并存在于数据库中。 已经修改了其部分或全部属性值。
Unchanged 1 实体正在由上下文跟踪,并存在于数据库中。 不会更改数据库中的值的属性值。

适用于

适用于
产品 版本
Entity Framework Core 1.0, 1.1, 2.0, 2.1, 2.2, 3.0, 3.1, 5.0

 

声明:本站内容来源于原创和互联网,尊重作者版权,转载请注明来源网址,欢迎收藏,谢谢!