介绍
我的应用程序从一个集中的来源收集数据,许多不同的用户可以在其中提交有关其组织和员工的数据。以前,当用户数据与事实来源不再相关时,我们只是硬删除用户数据,因为它曾经是可靠的。
但是对客户使用的某些软件进行更改,一切都会变得混乱。现在,他们每月在提交数据时会多次删除所有数据。这是错误的,并且由于设计糟糕。这意味着他们丢失了我们系统中用户的数据,并且必须重新输入其中的一部分。
他们使用的软件很顽固,不会改变行为。我们已经尝试教育用户如何使用它,但他们没有学习。所以现在最后一个选项是软删除一段时间内的数据。
看过网络上的多个 Stack Overflow 帖子和博客后,我真的不喜欢任何选项,IE。在需要软删除的表中添加一列。我开始寻找是因为这也是我的第一直觉,但我并不真正喜欢它及其含义。
我想知道你是否可以就不同的想法给我一些反馈。我没有维护软删除的经验,我不知道我的想法是否很糟糕。
有一个用户,他们的唯一标识符在多个组织中是相同的。每个用户隶属于一个组织,他们有一些用户信息,如姓名、头衔等。在我们的系统中,他们有一个状态行,因为无论他们选择连接哪个组织,在我们的应用程序中都是相同的。
因此,如果我按照传统方式添加用于软删除的列,我将不得不为每个包含用户数据的唯一表添加一个,因为它们与某个组织的从属关系可能会被删除,但作为用户,它们仍然存在我们的系统来自其他地方。
但是,为了解决所有这些额外的列,我的代码的实质内容似乎很麻烦,而且需要进行大量更改。
主意
在我看来,如果我添加一个包含以下内容的单独表格会更简单:
- 唯一用户标识符
- 唯一组织标识符
- 软删除日期
然后每当我的应用程序请求数据时,api 都会检查新表;“这个人是不是被本组织软删除了?” 如果为真,它们只会阻止请求,直到它们在需要时被恢复,或者它们将一直被删除,直到它们在软删除发生后的 x 小时内被硬删除。
不必到处更改许多查询和逻辑。
附加信息
该 API 使用 EFCore 作为 ORM 来连接到数据库,以防它有助于解决有关其功能集的任何其他智能修复。我曾考虑过创建自定义保存更改逻辑,但除了再次向所有表中添加一列之外,我想不出一个好主意。
如果您需要更多信息,请告诉我。
更新
JD 告诉我行级安全性,这让我环顾四周。它似乎非常有用,它让我对我可以搜索的内容有了更多的了解。
所以我遇到了 EFCore 的全局查询过滤器,这似乎很有希望。它允许上下文对所有查询进行过滤,当您实际上需要忽略此全局过滤器时,您可以简单地逐个查询地执行此操作。
如果您需要为基于连接用户的全局过滤器使用某些东西,它允许依赖注入。我根据这些新信息创建了一个答案
事实证明,我真正想要的是停用该行,直到最终激活或硬删除而不是软删除。我不知道表达自己的正确方式。
JD 在评论中提到了行级安全性,对于需要做我想做的事但只能使用 SQL 的人来说,这似乎很有希望。如果他们发布答案,我会为这个问题给予他们信任。
尽管可以在 EFCore 中创建允许在部署数据库时执行自定义 SQL 的迁移,但感觉是被迫的。但仍然可能是一个有效的解决方案
MS docs 自定义迁移功能
MS docs 原始迁移 SQL
JD 的 ROW 级安全链接
根据我词汇表中的新术语,我从 EFCore 中找到了全局查询过滤器,然后我就去了。
微软自己的文档
尽管您确实需要小心设置它的方式。
但从本质上讲,它归结为在代码优先配置中添加这样的内容。
博客讨论一个真实世界的例子,他们讨论将用户 JWT 令牌信息注入上下文以允许对个人进行个人过滤。
该博客讨论了将默认的 savechanges 功能覆盖为始终软删除,但这不是我想要的,但有些人可能会觉得它很有帮助。
最终实施
我有所有相关模型继承自
Deactivateable
将属性/列添加到数据库。然后由于过滤器的简单性,我只是在上下文中创建了这个配置:基于stevendarby发表的这个github 问题评论的灵感。我不知道它们是从哪里来的,所以我只是选择自己迭代模型并查看子类,基于我在相关 SO 帖子中看到的一个想法,我再也找不到和参考了。
.Model.FindLeastDerivedEntityTypes