简体   繁体   中英

Cannot access a disposed object

i'm facing a issue while testing the DAL Library which uses LINQ to SQL

Method that is being Tested as below (a simple one):

public List<tblAccount> GetAccountsByCustomer(tblCustomer customer)
{
    using (OnlineBankingDataClassesDataContext dbcntx = new OnlineBankingDataClassesDataContext())
    {
        var accounts = dbcntx.tblAccounts.Where(p => p.tblCustomer.ID.CompareTo(customer.ID)==0);
        return accounts.ToList<tblAccount>();
    }
}

Test code is as below:

static tblCustomer GetTopOneCustomer()
{
    OnlineBankingDataClassesDataContext dbcntx = new OnlineBankingDataClassesDataContext();
    var customers = dbcntx.tblCustomers.Take(1);
    return customers.Single<tblCustomer>();
}

public static void Should_List_All_Account_By_Customer()
{

    tblCustomer customer = GetTopOneCustomer();

    DataController dc = new DataController();
    List<tblAccount> accounts=dc.GetAccountsByCustomer(customer);
    foreach (tblAccount account in accounts)
    {
        string accountdetails=string.Format("Account ID:{0} \n Account Type:{1} \n Balance:{2} \n BranchName:{3} \n AccountNumber:{4}",
                        account.ID.ToString(), account.tblAccountType.Name, 
                        account.Balance.ToString(),
                        account.tblBranch.Name, account.Number);

        Console.WriteLine(accountdetails);

    }
}

I'm getting an error "Cannot access a disposed object." when accessing associated object like in this case, I'm using account.tblAccountType.Name . I know it has something to do with DataContext . How shall I get this code working.

dbcntx is a disposable object. The Garbage Collector can come along at any time after GetTopOneCustomer() has been called and dispose of it. Which is what looks like is happening.

Try changing GetTopOneCustomer() to:

static tblCustomer GetTopOneCustomer(OnlineBankingDataClassesDataContext dataContext) 
{
    //Stuff
}

Then inside Should_List_All_Account_By_Customer() change it like so:

using (OnlineBankingDataClassesDataContext dataContext = new OnlineBankingDataClassesDataContext())
{
    tblCustomer customer = GetTopOneCustomer(dataContext); 
    //More Stuff
}

This way you control the lifetime of the dataContext .

Since the the DataContext is in a using statement, using (OnlineBankingDataClassesDataContext dbcntx = new OnlineBankingDataClassesDataContext()) Disposed will be called on it as soon as the context goes out of scope. This results in all entities beeing detached and all actions on the entity that requires a DataContext will fail. This is what happens when account.Balance.ToString() is called.

One way to solve this is by creating a new context and use context.Attach(entity) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM