【问题标题】:ASP.NET Entity Framework DataContext use issueASP.NET Entity Framework DbContext 使用问题
【发布时间】:2014-01-24 18:24:02
【问题描述】:

我已经使用 EF 构建了一个 ASP.NET 网站。我创建了一个实现单例模式的 DataContext 类。我的 DAO 类(也是单例)实例化了这个数据上下文并将其存储在一个属性中。他们使用它来查询 SQLServer 数据库。这工作了 3 个月,但我突然收到异常消息,例如:“连接必须有效并且打开/连接已经打开”。似乎没有处理数据上下文。在我看来,唯一的变化是数据大小和用户数量的增加。

然后我发现多个帖子说单例对数据上下文来说是个坏主意,所以我尝试在每个请求的 using 语句中实例化数据上下文并解决了问题,除了对数据库没有影响的更新查询。我必须将 db 对象附加到上下文,然后将其 EntityState 设置为“已修改”以使我的 SaveChanges 工作。

像这样:

public bool DoucheXpsu(as_headers session) {
    using (MyDBEntities MyContext = new MyDBEntities()) {

        try {
            as_status status = GetStatus(session);
            if (status != null) {
                if (status.mainstatusvalue == 300) {
                    status.DateDoucheXpsu = DateTime.Now;
                    status.DoucheXpsu = 1;

                    MyContext.as_status.Attach(status);
                    MyContext.ObjectStateManager.ChangeObjectState(status, EntityState.Modified);

                    MyContext.SaveChanges();

                    return true;
                } else {
                    return false;
                }
            } else {
                return false;
            }
        } catch (OptimisticConcurrencyException) {
            return false;
        } catch (Exception) {
            return false;
        }
    }
}

问题在于它实际上不适用于 ONE 方法(与其他更新方法没有什么不同)! 当我尝试附加对象时发生异常:“无法附加对象,因为它已经在对象上下文中。对象只能在处于未更改状态时重新附加。”所以我不得不评论附加和 ChangeObjectState让它按预期工作的方法:

public bool SetSessionToDelete(string numSession) {
    using (MyDBEntities MyContext = new MyDBEntities()) {
        try {
            view_headerStatus view = (from v in MyContext.view_headerStatus
                                      where v.CodeSession == numSession
                                      where v.lastinserted == 1
                                      select v).First();

            if (view != null) {
                as_status status = (from s in MyContext.as_status
                                    where s.jobclsid == view.jobclsid
                                    where s.lastinserted == 1
                                    select s).First();
                if (status != null) {
                    status.DeleteSession = 1;
                    //MyContext.as_status.Attach(status);
                    //MyContext.ObjectStateManager.ChangeObjectState(status, EntityState.Modified);
                   MyContext.SaveChanges();
                    return true;
                } else {
                    return false;
                }
            } else {
                return false;
            }

        } catch (OptimisticConcurrencyException) {
            return false;
        } catch (Exception) {
            return false;
        }
    }
}

问题是为什么这个行为会有所不同??? 我读过很多关于 EF 和 dataContext 的帖子,但我觉得我遗漏了一些东西。如果有人可以提供帮助,我会很高兴。 谢谢。

【问题讨论】:

    标签: asp.net entity-framework datacontext


    【解决方案1】:

    在您的第一个示例中,此行:

    as_status status = GetStatus(session);
    

    我假设它使用不同的上下文填充,并且当它离开 GetStatus() 方法时,它用于加载的上下文被释放。这就是您后续的 Attach() 有效的原因。但是,在您的第二个示例中,您不需要附加,因为它是使用当前(连接的)上下文加载的。

    要解决此问题,您可能希望将上下文传递给 GetStatus() 等方法,从而无需重新附加。我通常不会重新连接,除非我通过电线或文件复活一个对象。

    【讨论】:

    • 天啊!你是对的,当然!现在你这么说听起来很明显。谢谢,真的很有帮助。
    猜你喜欢
    • 1970-01-01
    • 2020-08-18
    • 2014-05-04
    • 2022-11-21
    • 2010-09-24
    • 2015-06-10
    • 2016-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多