2012-07-06 2 views
0

я обращенный к проблеме во время тестирования библиотеки DAL, который использует LINQ для SQLНе удается получить доступ к расположенному объекту

метода, который испытывается, как показано ниже (простая один):

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

Тест кода как указано ниже:

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

    } 
} 

Я получаю сообщение об ошибке «Не удается получить доступ к расположенному объекту». при доступе к связанному объекту, как в этом случае, я использую account.tblAccountType.Name. Я знаю, что это имеет какое-то отношение к DataContext. Как мне заставить этот код работать.

ответ

1

dbcntx - одноразовый объект. Сборщик мусора может прийти в любое время после того, как было вызвано и утилизировано GetTopOneCustomer(). Это то, что похоже на происходящее.

Попробуйте изменить GetTopOneCustomer() к:

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

Затем внутри Should_List_All_Account_By_Customer() изменить его следующим образом:

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

Таким образом, вы контролируете срок службы dataContext.

+0

Обычно я обертываю их в класс, так как класс активен, соединение с базой данных будет активным. – Trisped

+0

@DaveShaw Проблема заключается в том, что связанные объекты обращаются к объектам после того, как был удален DataContext dbcntx. GetTopOneCustomer не должен создавать никаких проблем. – JonC

0

Поскольку DataContext находится в операторе using, using (OnlineBankingDataClassesDataContext dbcntx = new OnlineBankingDataClassesDataContext()) Disposed будет вызываться на него, как только контекст выходит за рамки. Это приводит к отключению всех объектов, и все действия над объектом, требующим DataContext, потерпят неудачу. Это то, что происходит, когда вызывается account.Balance.ToString().

Один из способов решения этой проблемы - создать новый контекст и использовать context.Attach(entity).

+0

где используется оператор 'DataContext'? – Trisped

+0

В GetAccountsByCustomer. – JonC

+0

А, не прокрутил достаточно. – Trisped

Смежные вопросы