Ошибка потока объектного контекста .Net Entity

У меня есть многоуровневое приложение asp.net, которое возвращает объект из моего DAL в BAL следующим образом:

public IEnumerable<SourceKey> Get(SourceKey sk)
{
    var query = from SourceKey in _dataContext.SourceKeys
                select SourceKey;

    if (sk.sourceKey1 != null)
    {
        query = from SourceKey in query
                where SourceKey.sourceKey1 == sk.sourceKey1
                select SourceKey;
    }

    return query.AsEnumerable();
}

Этот результат проходит через мой бизнес-уровень и попадает на уровень пользовательского интерфейса для отображения конечным пользователям. Я не использую ленивую загрузку, чтобы предотвратить выполнение запроса в других слоях моего приложения.

Я создал еще одну функцию в своем DAL для удаления объектов:

public void Delete(SourceKey sk)
{
    try
    {
        _dataContext.DeleteObject(sk);
        _dataContext.SaveChanges();
    }
    catch (Exception ex)
    {
        Debug.WriteLine(ex.Message + " " + ex.StackTrace + " " + ex.InnerException);
    }
}

Когда я пытаюсь вызвать «Удалить» после вызова функции «Получить», я получаю эту ошибку:

Новая транзакция не разрешена, поскольку в сеансе выполняются другие потоки.

Это приложение ASP.Net. Мой DAL содержит модель данных объекта. Класс, в котором у меня есть вышеуказанные функции, использует один и тот же _dataContext, экземпляр которого создается в моем конструкторе. Я предполагаю, что ридер все еще открыт из функции "Получить" и не был закрыт. Как я могу закрыть его?

В моем слое пользовательского интерфейса я перебираю результаты и пытаюсь удалить их следующим образом:

foreach(SourceKey sk in skm.Get(new SourceKey()))
{
    Debug.WriteLine(sk.sourceKey1);

    skm.Delete(sk);
}

Изменить

Ошибка возникает в этой строке:

_dataContext.DeleteObject(sk);

person Chris Klepeis    schedule 24.05.2010    source источник


Ответы (1)


Я подозреваю, что это связано с обработкой запроса Linq. Я предполагаю, основываясь на статьях, которые я читал в прошлом, но я думаю, что ваш запрос выполняется лениво - запрос открывается с точки, в которой нумератор используется впервые (первый вызов MoveNext), и не закрывается пока не завершится перечисление.

Если вы контролируете перечисление, вы можете убедиться, что перечислитель завершится, и посмотреть, имеет ли это какое-либо значение. Или, что более вероятно, где-то есть конфигурация, которая может управлять выполнением запроса, но это выходит за рамки того, на что я смотрел.

person Dan Puzey    schedule 24.05.2010
comment
Насколько я понял, запрос был бы выполнен на AsEnumerable(). Я удалил удаление из цикла foreach, и это сработало. - person Chris Klepeis; 24.05.2010