“因为DbContext已被释放,所以无法完成操作。”

3

我刚接触实体框架代码优先,正在构建一个小型应用程序来熟悉它。当网站第一次运行时,我会访问数据库中现有的目录值,并使用Razor在下拉列表中显示。

public void GetCats()
    {
        using (context = new RecipeContext())
        {
            try
            {
                var query = (from r in context.Catalogues
                             select r).Distinct().ToList();

                catalogues = query.Select(t => t.CatalogueName.ToString()).ToList();
                catalogues.Sort();


            }
            catch (Exception exe)
            {
                labMessage = exe.Message;

            }

        }
    }

现在,当我尝试将目录值添加到上下文中时,我会遇到上述错误。
public void AddCatalogue(string catalogueName)
    {

        using(context = new RecipeContext())
        {
            try
            {
                catalogueName = catalogueName.ToLower();
                var catalogue = new RecipeCatalogue { CatalogueName = catalogueName };

                if (context.Catalogues.Where(t => t.CatalogueName == catalogueName).Count() > 0)
                {
                    labMessage = "The value already exists";
                    CatalogueNameAdded = false;
                    return;

                }
                context.Catalogues.Add(catalogue);
                context.SaveChanges();
                catalogueNameAdded = true;
                labMessage = "a new catalogue record was added";


            }
            catch (Exception exe)
            {
                catalogueNameAdded = false;
                labMessage = exe.Message;
            }

        }
    }

数值正在被添加到数据库中,但仍然会出现上述异常。

也许可以提供一些关于出现错误的建议。这是调用上述方法的控制器方法。

[HttpPost]
    public JsonResult AddNewCatalogue(string catalogueName)
    {
        ViewModel model = new ViewModel();
        model.AddCatalogue(catalogueName);
        return Json(new { ViewModel = model });

    }

我猜你应该检查哪段代码导致了context被释放。 - ebram khalil
1
您的模型中是否有上下文字段?如果有,您是否在这里复制的方法之外对其进行了任何操作?因为如果您这样做了,那么您正在使用已释放的上下文(它在using语句的闭合括号处被释放)。 - smv
可能是重复的问题:操作无法完成,因为DbContext已被释放 - JabberwockyDecompiler
3个回答

6
你的模型中有一个名为context的字段吗?我认为在using语句中不应该给一个字段赋值。使用语句的右括号被执行时,就会释放资源。如果你在其他地方访问该字段(未重新分配),那么你正在访问一个已经被释放的对象,这可能会导致你遇到的异常。尝试像这样更改using语句: using (var context = new RecipeContext()) (注意,在context之前有一个var),并删除这个字段。

@Arianule:但是它并没有解释发布的代码中的错误。 - H H
我的猜测是,异常是由另一个方法引发的,在任何已发布的方法处理完上下文后仍在使用它。 - smv

4

当您执行查询的using块退出时,您的上下文将被处理掉。这就是using语句的全部意义:

using(context = new RecipeContext()) {
    // ...
}
// context has been disposed at this point

不要使用 using 语句,给你的类一个字段来持有对它的引用。

private RecipeContext _context;

public void GetCats() {
    _context = new RecipeContext();
    // ...
}

public void AddCatalogue(string catalogueName) {
    // Use _context here
}

请确保在某些时候调用 _context.Dispose()。另外,最好在构造函数或仅在执行任何操作之前调用的其他位置创建上下文。


0

仅供参考:

以上答案是正确的!如果您正在使用某种模式,例如存储库,则建议将其实现为单例!这样,您的对象将不会被分离,您的上下文也不会被处理!


1
仓储应该返回一个List<T>。然后实现急切加载,DbContext可以被处理。阅读这个答案https://dev59.com/I3XYa4cB1Zd3GeqP9r2q - Michael Chudinov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接