【问题标题】:How to solve this error "The ObjectContext instance has been disposed and can no longer be used for operations that require a connection"如何解决此错误“ObjectContext 实例已被释放,不能再用于需要连接的操作”
【发布时间】:2014-11-21 09:38:25
【问题描述】:

我试图在两个不同的 dbContext 中使用相同的对象。我收到了这个错误

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

这个错误的可能原因是什么?

public string ValidateNXT_MODULE_DETAILS_PHARMACY(int id)
{
    long? ValCounter = 0;
    string prepQu = Constante.CurrentUser.LOG_USER; ;
    DateTime dateQu = DateTime.Today;
    NXT_MODULE_DETAILS_PHARMACY module = new NXT_MODULE_DETAILS_PHARMACY();

    try
    {
        using (CaseManagerEntities db = new CaseManagerEntities())
        {                    
            NXT_MODULE_DETAILS_PHARMACY cmd = db.NXT_MODULE_DETAILS_PHARMACY.Find(id);                    
            module = cmd;
        }                

        using (PHStockEntities db = new PHStockEntities())
        {
            using (TransactionScope t = new TransactionScope())
            {
                NXT_PH_COUNTER Counter = db.NXT_PH_COUNTER.Where(nat => nat.TYPE_CHOIX == 301).First();
                ValCounter = Counter.Value;
                Counter.Value = ValCounter + 1;                        

                foreach (var detail in module.NXT_MODULE_DETAILS_PHARMACY_DETAIL.ToList())
                {

                    NXT_PH_CHOIX_MODULE choix = db.NXT_PH_CHOIX_MODULE.Where(nat => nat.TYPE_CHOIX == 301).First();
                    NXT_ASS_ART_LOT_DEP_EC association = db.NXT_ASS_ART_LOT_DEP_EC.Where(nat => nat.ID_ARTICLE == detail.ID_LIST_PH_DET && nat.ID_LIST_DEPOT == module.DEPOT).First();

                    decimal? QTE = 0;
                    if (choix.SIGNE_STOCK == "P")
                    {
                        QTE = detail.QTE_PH_DET;
                    }
                    else if (choix.SIGNE_STOCK == "M")
                    {
                        QTE = decimal.Negate(decimal.Parse(detail.QTE_PH_DET.ToString()));
                    }
                    switch (choix.CHAMP_STOCK)
                    {
                        case "STOCK_VENTE":
                            association.STOCK_VENTE = association.STOCK_VENTE + QTE;
                            break;
                        case "STOCK_ACHAT":
                            association.STOCK_ACHAT = association.STOCK_ACHAT + QTE;
                            break;
                        case "STOCK_MOUVEMENT":
                            association.STOCK_MOUVEMENT = association.STOCK_MOUVEMENT + QTE;
                            break;
                        case "STOCK_ETAGE":
                            association.STOCK_ETAGE = association.STOCK_ETAGE + QTE;
                            break;
                    }
                }

                db.SaveChanges();
                t.Complete();
            }
        }

        using (CaseManagerEntities db = new CaseManagerEntities())
        {
            using (TransactionScope t = new TransactionScope())
            {
                module.NBR_QUITTANCE = ValCounter.ToString();
                module.DATE_QUITTANCE = dateQu;
                module.PREPART_QUITTANCE = prepQu;
                module.STATUT = 3;
                dbCaseManager.SaveChanges();
                t.Complete();
            }
        }
        return ValCounter.ToString() + ";" + prepQu + ";" + dateQu.Date;
    }
    catch (Exception e)
    {
        return "ERROR";
    }        
}

【问题讨论】:

  • 在“foreach (var detail in module.NXT_MODULE_DETAILS_PHARMACY_DETAIL.ToList())”中抛出异常

标签: c# entity-framework


【解决方案1】:

这段代码……

using (CaseManagerEntities db = new CaseManagerEntities())
{                    
    NXT_MODULE_DETAILS_PHARMACY cmd = db.NXT_MODULE_DETAILS_PHARMACY.Find(id);
    module = cmd;
}                

...创建module 并立即释放它所连接的上下文。之后,您尝试延迟加载 module 的成员,这需要实时上下文。

您必须将右大括号移到代码底部,就在return 语句之前。

另一个问题是,稍后,您修改 module,但在 dbCaseManager 上调用 SaveChanges() - 不管是什么,它不是跟踪 module 的上下文。所以module 没有保存。

旁注:帮自己一个忙,不要使用这些可能直接从数据库名称中冒出来的可怕的大写/前缀/下划线名称。 O/R 映射器的想法是,您可以将更友好的名称映射到这些数据库名称,无论出于何种原因,这些名称通常看起来都像这些怪物。

进一步:这些TransactionScopes 是没用的。 SaveChanges 管理自己的事务:它要么成功要么回滚它尝试提交的所有内容。

【讨论】:

    【解决方案2】:

    您在第一个 using 语句中处理了 CaseManagerEntities,因此导航属性的任何进一步延迟加载都是尝试使用处理的上下文获取数据。解决此问题的一种方法是急切加载您需要的实体。假设NXT_MODULE_DETAILS_PHARMACY 的主键是 id,试试这个:

    var cmd = db.NXT_MODULE_DETAILS_PHARMACY.Include(x => x.NXT_MODULE_DETAILS_PHARMACY_DETAIL).Single(x => x.id == id);
    

    【讨论】:

    • 我遇到了这个错误:NXT_MODULE_DETAILS_PHARMACY 不包含“包含”的定义
    • 对不起,我的顺序错了,我已经更新了我的答案。
    • 现在我收到这个错误:无法将 lambda 表达式转换为类型“字符串”,因为它不是委托类型
    • 确保你有using System.Data.Entity;
    猜你喜欢
    • 2013-08-26
    • 2013-07-15
    • 1970-01-01
    • 2012-07-17
    相关资源
    最近更新 更多