【问题标题】:ASP.Net Entity Framework, objectcontext errorASP.Net 实体框架,对象上下文错误
【发布时间】:2010-05-21 17:49:46
【问题描述】:

我正在构建一个 4 层的 ASP.Net Web 应用程序。 这些层是:

  1. 数据层
  2. 实体层
  3. 业务层
  4. UI 层

实体层具有我的数据模型类,并且是使用 T4 模板 (POCO) 从数据层中的我的实体数据模型(edmx 文件)构建的。实体层在所有其他层中都被引用。

我的数据层有一个名为 SourceKeyRepository 的类,它的功能如下:

public IEnumerable<SourceKey> Get(SourceKey sk)
{
    using (dmc = new DataModelContainer())
    {
        var query = from SourceKey in dmc.SourceKeys
                    select SourceKey;

        if (sk.sourceKey1 != null)
        {
            query = from SourceKey in query
                    where SourceKey.sourceKey1 == sk.sourceKey1
                    select SourceKey;
        }

        return query;
    }
}

延迟加载已禁用,因为我不希望我的查询在此应用程序的其他层中运行。尝试访问 UI 层中的信息时收到以下错误:

ObjectContext 实例已被 处置,不能再用于 需要连接的操作。

我确定这是因为我的 DataModelContainer“dmc”已被处置。如何从我的数据层返回此 IEnumerable 对象,使其不依赖于 ObjectContext,而仅依赖于 DataModel?

有没有办法限制延迟加载只发生在数据层?

【问题讨论】:

    标签: .net lazy-loading objectdisposedexception objectcontext


    【解决方案1】:

    query 是惰性求值的,因此在枚举之前不会从数据库中检索数据。

    如果你这样做:

    return query.ToList();
    

    您将强制执行查询并避免问题。

    您收到错误消息是因为当调用者枚举集合时,由于您的 using 子句,ObjectContext (dmc) 已经被释放(这很好 - 尽早释放与数据库相关的资源!)

    编辑

    在原来的帖子中,我使用了AsEnumerable(),我认为这是正确的——直到我最近自己尝试在这种情况下使用它。 AsEnumerable() 只进行编译时类型转换 - 它不枚举。要强制枚举查询,必须将其保存在 List 或其他集合中。

    【讨论】:

    • 刚刚尝试过:'System.Linq.IQueryable' 不包含“ToEnumerable”的定义,并且没有扩展方法“ToEnumerable”接受“System.Linq”类型的第一个参数.IQueryable' 可以找到(您是否缺少 using 指令或程序集引用?)
    • 抱歉,我混淆了名称 - 正如 Tomas 建议的那样,它应该是 AsEnumerable。我已经更新了我的答案。
    • 我对其进行了调整,现在它抛出了 ObjectContext 已处理的原始消息。
    • 它不喜欢当我在使用中得到回报时......我把它拿出来了,现在它很好去。谢谢
    • 这对我不起作用,我仍然收到错误
    【解决方案2】:

    你可以在query对象上调用一些方法,例如

    return query.AsEnumerable();
    

    这应该确保您执行查询,从而确保您以后不需要对象上下文。

    【讨论】:

      【解决方案3】:

      不要使用

      return query.AsEnumerable();
      

      使用

      return query.ToArray();
      

      在处理你的上下文之前。

      在引用对象之前,返回 AsEnumerable 不会执行 foreach。将其转换为数组可确保在处理对象之前执行 foreach。然后,您可以将上下文放在 using 块中(您应该这样做)。

      【讨论】:

      【解决方案4】:

      在我看来,这种情况与 AsEnumerable() 或 AsQueryable() 无关。试试这个;

       public IEnumerable<SourceKey> Get(SourceKey sk, DataModelContainer dmc) {    
      
          var query = from SourceKey in dmc.SourceKeys
                      select SourceKey;
      
          if (sk.sourceKey1 != null)
          {
              query = from SourceKey in query
                      where SourceKey.sourceKey1 == sk.sourceKey1
                      select SourceKey;
          }
      
          return query;
      

      }

      你必须得到这个属性

      using (dmc = new DataModelContainer()) {
       // GET
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-11-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-08
        • 2013-05-08
        相关资源
        最近更新 更多