C. Knight
C. Knight

Reputation: 749

Pass Dbcontext to inner method being disposed

First off - apologies if this is trivial. I've done some searching but can't find anything specifically relevant. Almost all of the questions I've found have concerned nested using statements - which does not apply in my case.

The problem: I have a method which instantiates an instance of my DbContext. This instance is then passed into a private method which performs some actions, the context is then disposed of in the outer method. As soon as I try and use the context in the inner method, I get the good old exception:

The operation cannot be completed because the DbContext has been disposed

The Question: What have I missed? How is the context being disposed, and is there a way to prevent this? As you can see from the code below I'm using recursion, so creating a DbContext in the inner method is probably not a good idea.

The Code:

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;
    });
}

Upvotes: 2

Views: 757

Answers (2)

Evk
Evk

Reputation: 101443

You return IEnumerable from GetContent. That means your last Select in GetContent will not be executed immediately (Select is lazily evaluated), it will be executed only when something enumerates the result of GetContent. But when something enumerates result of GetContent - your context is already disposed. Inside that Select you call content.GetChildContent(context). This method assumes context is alive but it is not.

One fix is enumerate result yourself before returning from the method:

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

Upvotes: 3

Sunny Jangid
Sunny Jangid

Reputation: 578

  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;
            });
        }

Upvotes: -2

Related Questions