将Dbcontext传递给正在处理的内部方法

时间:2017-06-26 10:12:12

标签: c# entity-framework dispose dbcontext

首先 - 如果这是微不足道的话,道歉。我做了一些搜索,但找不到任何特别相关的内容。我发现的几乎所有问题都涉及嵌套使用语句 - 这在我的案例中不适用。

问题: 我有一个实例化我的DbContext实例的方法。然后将此实例传递给执行某些操作的私有方法,然后在外部方法中处理上下文。一旦我尝试在内部方法中使用上下文,我就会得到好处:

“操作无法完成,因为DbContext已被处理”异常。

问题: 我错过了什么?如何处理上下文,是否有办法防止这种情况发生? [从下面的代码中我可以看到我正在使用递归,因此在内部方法中创建DbContext可能不是一个好主意。

守则:

    public static IEnumerable<Content> GetContent(int? parentId = null)
    {
        using(DSSCMSContext context = new DSSCMSContext())
        {
            return context.Contents.Where(x => x.ParentId == parentId).ToList().Select(x => 
                {
                    Content content = new Content(x);
                    content.GetChildContent(context);
                    return content;
                });          
        }
    }

    private void GetChildContent(DSSCMSContext context)
    {
        Children = context.Contents.Where(x => x.ParentId == Id).ToList().Select(x =>
        {
            Content child = new Content(x);
            child.GetChildContent(context);
            return child;
        });
    }

2 个答案:

答案 0 :(得分:3)

您从IEnumerable返回GetContent。这意味着Select中的最后一个GetContent将不会立即执行(Select被延迟评估),只有在列举GetContent的结果时才会执行。但是当枚举GetContent的结果时 - 你的上下文已经被处理掉了。在Select内,您拨打content.GetChildContent(context)。此方法假设上下文仍然存在,但事实并非如此。

一个修复是在从方法返回之前自己枚举结果:

return context.Contents.Where(x => x.ParentId == parentId).AsEnumerable().Select(x => 
{
     Content content = new Content(x);
     content.GetChildContent(context);
     return content;
}).ToList(); 

答案 1 :(得分:-2)

  public static IEnumerable<Content> GetContent(int? parentId = null)
    {
        using(DSSCMSContext context = new DSSCMSContext())
        {
            return context.Contents.Where(x => x.ParentId == parentId).ToList().Select(x => 
                {
                    Content content = new Content(x);
                    content.GetChildContent(context);
                    return content;
                });          
        }
    }

    private void GetChildContent(DSSCMSContext context)
    {
        Children = context.Contents.Where(x => x.ParentId == Id).ToList().Select(x =>
        {
            Content child = new Content(x);
            child.GetChildContent(context);
child.Dispose();
                return child;
            });
        }