Ошибка LINQ to SQL: «Невозможно выполнить операцию во время вызова SubmitChanges». - PullRequest
0 голосов
/ 02 ноября 2010

Хорошо, я получаю эту ошибку из строк:

  System.Data.Linq.DataContext.CheckNotInSubmitChanges() +42
  System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode) +54

То, что я делаю, отслеживает состояние приложения и регистрирует каждый запрос. Приложение отображает выходные данные в форматах Json, Xml и Html.

Дело в том, что ошибка ошибочна. Это происходит только каждые несколько запросов. Ошибка начала происходить, когда я начал делать запросы Ajax. Я смог определить, что ошибка возникает чаще с быстрыми запросами (то есть, если я нажимаю на ссылку несколько раз).

Я создаю отдельный экземпляр DataContext каждый раз, когда вызываю службу, которая выдает ошибку. Мне действительно трудно понять, в чем здесь проблема, и я был бы очень признателен за любые указания и / или объяснения того, что происходит. Спасибо.

* РЕДАКТИРОВАТЬ: **

 [InvalidOperationException: The operation cannot be performed during a call to SubmitChanges.]
    System.Data.Linq.DataContext.CheckNotInSubmitChanges() +80
    System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode) +73
    Magic.Model.Sessions.SqlXmlSessionStore.SubmitChanges() in SqlXmlSessionStore.cs:17
    Magic.Model.Sessions.SqlXmlSessionStore.UpdateSession(Session session) in SqlXmlSessionStore.cs:64
    Magic.Web.SessionService.OpenSession(MagicRequestContext requestContext) in SessionService.cs:36
    Magic.Web.SessionService.Magic.Model.Sessions.ISessionService.OpenSession(IRequestContext requestContext) in SessionService.cs:23

Упомянутые методы:

private bool SubmitChanges()
{
   _sqlContext.SubmitChanges(ConflictMode.FailOnFirstConflict);
   return _sqlContext.ChangeConflicts.Count == 0;   
}

public bool UpdateSession(Session session)
{
   var record = _sqlContext.SessionRecords.Single(x => x.SessionId == session.Key);
   _converter.PopulateRecordData(session, record);
   return SubmitChanges();
}

Все, что делает класс обслуживания сеанса, это вызывает SqlXmlSessionStore.UpdateSession (сеанс), если сеанс находится в базе данных и активен, или SqlXmlSessionStore.InsertSession (сеанс), если запрос новый, а идентификатор сеанса отсутствует или уникален.

Я пытался создавать новый экземпляр DataContext каждый раз, когда выполнял SubmitChanges (), но это приводило к тому, что у меня не было объекта Connection, даже когда я получал одно и то же соединение. Строка из настроек. Может ли это быть что-то связанное с моей локальной машиной?

Хорошо, я сделал что-то, что работает, но я не уверен, что возникнет проблема с этим, которую я не предвидел.

Я разрешаю DataContext отправлять только один раз. Я сделал это, изменив код SubmitChanges () на:

    private bool _canSubmit = true;

    bool SubmitChanges(){
        if(_canSubmit)
        {
            _sqlContext.SubmitChanges(ConflictMode.FailOnFirstConflict);
            _canSubmit = false;
            return _sqlContext.ChangeConflicts.Count == 0;      
        }
        return false;
     }

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

Ответы [ 3 ]

1 голос
/ 02 ноября 2010

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

EDIT

Я не понимаю, как управляется время жизни DataContext. В первой части вопроса вы говорите

Я создаю отдельный экземпляр DataContext каждый раз, когда я вызываю обслуживание

но во второй части вы говорите

Я пытался создать новый экземпляр DataContext каждый раз, когда я сделал SubmitChanges (), но это привело к у меня нет объекта Connection

Следующее, что я не понимаю, это то, как ваш измененный метод, который вызывает SubmitChanges только один раз, работает, так как он отбрасывает любые изменения в данных, сделанные после первого вызова, он должен либо не регистрировать все ваши данные, либо любой вызов после первый вызов для отправки изменений не требуется.

Методы экземпляра Datacontext не являются потокобезопасными, вы не можете поместить их в глобальную переменную при запуске приложения (вы это делаете?); Вы обычно хотите новый Datacontext для каждого HTTP-запроса, который вы можете сделать с помощью инфраструктуры Inversion of Control или просто в коде, создать новый код данных в начале запроса и вызвать в конце изменения отправки.

Другой метод - использовать несколько DataContexts, создать текстовый текст данных, внести изменения, вызвать отправку изменений, отбросить DataContext, он очень легкий. Вам не нужно часто вызывать изменения при отправке более одного раза. Единственный раз, когда я это делал, это управлял порядком выполнения операторов SQL.

Было бы хорошо, если бы вы могли создать минимальный пример и опубликовать весь код.

1 голос
/ 05 ноября 2010

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

О, и причина, по которой это влияло на мой DataContext, заключалась в том, что классы, которые обернули экземпляры Datacontext, были внутри блокировки.

0 голосов
/ 02 ноября 2010

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

Либо переопределите SubmitChanges и зарегистрируйте трассировку стека при каждом вызове, чтобы отследить оригинал ошибки.

...