使用附加子句更新实体

时间:2019-04-29 16:14:53

标签: c# asp.net .net entity-framework entity-framework-core

我目前正在开发基于列的多租户应用程序。 我在带有基类的每个实体上添加了tenantId,并使用了完全符合我需要的查询过滤器。 我还重写了savechanges方法,以使用changetracker在添加的实体上填充tenantid属性。

但是现在我被更新和删除所困扰。 据我所知,ef生成仅具有主键的where子句,这对我来说是非常不安全的,因为我在具有很多附加/分离内容的api环境中工作,并编写了很多entity.state = Modifyed首先是查询,以提高性能。

我的问题是:如何在ef核心更新/删除语句中添加谓词?

我知道我可以: 1.首先查询(我很确定你会建议我这样做) 2.将tenantid用作Compositekey的一部分,但是要将我的所有代码重构为add / find / etc确实很痛苦。方法需要完整的主键。

我将非常感谢任何知道如何触发此操作的人!

1 个答案:

答案 0 :(得分:2)

选项3:

尽管不是为此而设计的,但是您可以使用EF Core Optimistic concurrency control为您执行安全检查:

  

在关系数据库上,EF Core包含对任何WHEREUPDATE语句的DELETE子句中并发令牌值的检查。执行这些语句后,EF Core读取受影响的行数。   如果没有受影响的行,则检测到并发冲突,并且EF Core抛出DbUpdateConcurrencyException

想法是(1)通过TenantId属性或[ConcurrencyCheck]流利的API将IsConcurrencyToken()标记为并发令牌,并且(2)在SaveChanges覆盖内,使用当前租户TenantId设置Id属性值,不仅用于添加实体,还用于修改和删除实体。

这样做,EF Core将在AND TenantId == @currentTenantIdUPDATE命令中添加类似DELETE的命令,只有当当前租户与用于实体创建的租户匹配时,该命令才能成功。

缺点是异常类型/消息,并与现有的并发检查(如果使用)混合在一起。

更新SaveChanges中用于修改和删除实体的代码应设置OriginalValue属性条目的TenantId并重置IsModified标记:

var tenantIdEntry = entityEntry.Property("TenantId");
tenantIdEntry.OriginalValue = CurrentTenantId;
tenantIdEntry.IsModified = false;

如果TenantId属性已按照What is the best way to perform partial updates in EF core and never update certain properties?中的说明配置为AfterSaveBehavior = PropertySaveBehavior.Ignore,则不需要最后一个。