确定实体代理的上下文是否已被释放
本文关键字:是否 释放 上下文 实体 代理 | 更新日期: 2023-09-27 18:00:40
在一个EF 6项目中,我正在为实体编写验证函数。有些是静态的,而另一些是实体本身的实例方法。
忽略这是否是一种糟糕的做法,我想检查实体是否是使用上下文创建的,如果是,它们是否仍然是附加的。
请注意,这些函数不能访问上下文对象,只能访问实体类。
例如,一个方法验证Department
实体,并将验证级联到所有关联的Department.Employee
实例。
- 如果层次结构是手动创建的,则验证将成功
- 如果层次结构是使用仍然有效的上下文创建的,则验证将成功,尽管速度较慢
- 如果层次结构是使用已释放的上下文创建的,则验证将失败,并显示
ObjectDisposedException
(前提是启用了代理创建并且未使用.Include(***)
)
那么,问题是,在不访问DbContext
实例的情况下,是否可以检测到上述场景?如果不是,我们如何才能最好地验证整个层次结构,而不管它们是如何创建的。
var result = true;
var departments = ???; // Constructed manually or through a DbContext instance.
foreach (var department in departments)
{
result &= department.Validate();
foreach (var employee in department.Employees)
{
result &= employee.Validate();
}
}
编辑:请注意,这适用于不能具有长时间运行的DbContext
实例的桌面应用程序。它们几乎总是在检索数据之后立即被处理。重新查询数据库似乎不是一个可行的验证选项,因为它是由琐碎的用户输入触发的,会降低整个用户体验。
根据您的问题
请注意,这些函数不能访问上下文对象,只能访问实体类。
脑海中浮现出两种解决方案,但没有一种真正令人满意:
- 构建自己的跟踪器,并以某种方式使其可用于这些方法
- 向实体中添加一些内容,例如查询上下文时设置的
WasLoaded
属性。WasLoaded
可以由- 编写设置它的EF拦截器
- 添加一个所有值都设置为1的人工
bit
列。然后将其映射到属性;如果您在上下文之外构造属性,则该属性将为false
,如果从上下文加载,则为true
跟踪器似乎是最干净的,因为它不会污染你的模型。如果你不关心你的模型,拦截器是一个不错的选择。
虽然它不能直接回答你的问题,但你可以避免使用代理,在这种情况下,无论你的验证是以相同的方式进行的,因为你的模型在内存中。不过,也有一些常见的权衡需要考虑。
我不确定你是怎么发现最后一种情况的。我想你可以让你的追踪器追踪更多的实体。。。让它也跟踪上下文的状态。