实体框架,软删除和查询

6
这是我的情况:
我正在使用“IsDeleted”标记软删除表中的某些行,以便可以跟踪我的归档数据。我通过在我的“ObjectContext”中覆盖“SaveChanges”语句来实现这一点。
问题是:如何仅选择具有“IsDeleted == false”的行,而无需在每个查询中指定“&&!IsDeleted”?
是否有一种方法可以直接在上下文中指定这个?
谢谢!

EF Code-first还是Model-first? - StriplingWarrior
不要使用标志,而是使用表格。对于已删除的表格,主键可以与主表相同,已删除的表格的主键则是指向主表的外键。如果在已删除的表格中找到记录,则表示该记录已被删除,否则为活动状态。然后只需进行简单的连接即可。查询性能将优于使用位标志。 - Jon Raynor
@JonRaynor:数据库不是我的专长,但在我看来,检查一个位标志的成本肯定比进行连接要低得多,尤其是因为你通常更关心哪些项目没有被删除(因此不在已删除表中)。如果位标志影响查询性能,我更倾向于创建索引而不是完全单独创建一张表。 - StriplingWarrior
@Stripling - 表面上看起来是正确的。我在这里提出了一个后续问题。https://dev59.com/emox5IYBdhLWcg3w95A9 - Jon Raynor
3个回答

8
您可以定义一个视图并查询该视图,而不是直接查询表格:
CREATE VIEW dbo.ActiveData
AS
  SELECT (list of columns)
  FROM dbo.YourTable
  WHERE IsDeleted = 0

然后在您的 EDMX 模型中,从 ActiveData 视图读取数据,而不是基础表。


7
如果你在模型查看器中右键单击EntitySet,然后点击“表映射”,就会有一个可以“添加条件”的区域。这应该可以满足您的要求,尽管根据marc_s的建议,您最好使用视图而不是EntitySet。

条件映射是在EF中正确的方法。使用@marc建议的视图可以工作,但需要进行额外的更改。 - Ladislav Mrnka
你如何在 Code-First 中进行有条件的映射,而不需要物理 edmx 文件? - danludwig
@olivehour:http://stackoverflow.com/questions/8161689/entity-framework-conditional-mapping-with-code-first - StriplingWarrior
@StriplingWarrior 谢谢,基本上我们做的就是这样,只不过是通过IQueryable / IEnumerable扩展方法而不是直接在上下文中进行。 - danludwig
@StriplingWarrior:当你向实体添加条件IsDeleted = false时,该实体在edmx文件中就不能再包含IsDeleted。那么如果IsDeleted不能成为实体的一部分,你如何删除实体呢? - Bumper
@Bumper:我个人会在表上放置一个触发器来捕获删除操作,然后让实体框架实际发出"delete from..."指令。 - StriplingWarrior

1

这是一个旧问题,但对于任何新来的人。从EF 6开始,您真的应该使用拦截器来处理此类查询。它在运行时将查询放置在SQL查询内部,并根据标志过滤记录。

有关更多信息,请参见以下内容:

使用拦截器软删除实体


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接