0
votes

I am using Linq to SQL classes for the data extraction and have the below entities:

  • Customer -> Orders

Customer and Order are linked via a FK constraint on the CustomerID and appear in my .dbml file with that relationship

When I access the object properties via intellisense I can see Customer.Name, Customer.Address etc but also the linked Orders entity Customer.Orders

My issue is that when I query the database to populate the Customer entity only and dispose the Datacontext I get an error thrown

Cannot access a disposed object. Object name: 'DataContext accessed after Dispose.'.

public IEnumerable<Customer> GetCustomer(Int32 customerID)
        {
            // initialise
            Customer cust = new Customer();

           using (CustomerManager ctl = new CustomerManager())
            {
                // get customer, this returns a single customer entity
                // i.e. datacontext.Customers.Where(m=> m.CustomerID == customerID).FirstOrDefault();
                cust = ctl.SelectCustomer(customerID);

            }

            yield return cust;
}

I have tried changing this to a Stored procedure i.e. Customer_SelectResult and this works perfectly fine. It is when I use the tables.

Is there any way to prevent the child tables from causing this issue?

Thanks in advance

2
Just out of curiosity, why do you return an IEnumerable<Customer> if there is only one customer for a given id? - Peter Bons
Yes only the one customer but it still throws the error. - CR41G14

2 Answers

1
votes

You have to load all the data, before disposing. See https://msdn.microsoft.com/en-us/library/bb399393(v=vs.110).aspx for an explanation and https://msdn.microsoft.com/en-us/library/bb386920(v=vs.110).aspx for a solution.

Yielding the result creates another problem, the query is executed on the database when the result is iterated. See https://blogs.msdn.microsoft.com/charlie/2007/12/10/linq-and-deferred-execution/

0
votes

The keyword using automatically disposes the initialized object in it. I guess ctl is disposed after the GetCustomer is called. So you can try without it:

CustomerManager ctl = new CustomerManager()
yield return ctl.SelectCustomer(customerID);