确定是否已处置实体代理的上下文

时间:2015-07-01 09:35:41

标签: c# .net entity-framework

在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个实例的桌面应用程序。它们几乎总是在检索数据后立即处理。重新查询数据库似乎不是一个可行的验证选项,因为它是由琐碎的用户输入触发的,会降低整个用户体验。

1 个答案:

答案 0 :(得分:1)

从你的问题

  

请注意,这些函数无权访问上下文对象,只能访问实体类。

我想到了两个解决方案,没有一个真正令人满意:

  1. 构建自己的跟踪器并以某种方式使这些方法可用。
  2. 向您的实体添加内容,例如在查询上下文时设置的WasLoaded属性。 WasLoaded可以由任何一个设置
    1. 编写设置它的EF拦截器。
    2. 添加一个人工bit列,并将所有值设置为1.然后将其映射到该属性;如果您在上下文之外构造它,则属性为false,如果从上下文加载,则为true
  3. 跟踪器似乎是最干净的,因为它不会污染您的模型。如果你不关心你的模型,拦截器是一个不错的选择。

    虽然它没有直接回答您的问题,但您可以避免使用代理,在这种情况下,无论您的模型是否在内存中,您的验证都会以相同的方式运行。不过要考虑通常的权衡取舍。

    我不确定你是怎么发现最后一个场景的。我想你可以让你的跟踪器比实体跟踪更多......让它跟踪上下文的状态。