LINQ ERRÁTICO PARA SQL ERRO: "A operação não pode ser realizada durante uma chamada para submeter -se".

StackOverflow https://stackoverflow.com/questions/4075367

Pergunta

Ok, então estou recebendo esse erro das linhas:

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

O que estou fazendo é rastrear o estado de um aplicativo e registrar cada solicitação. O aplicativo fornece saída em JSON, XML e HTML.

O problema é que o erro é irregular. Isso só acontece a cada poucos pedidos. O erro começou a acontecer quando comecei a fazer solicitações de Ajax. Consegui determinar que o erro ocorre com mais frequência com solicitações rápidas (ou seja, se eu clicar em um link repetidamente).

Estou criando uma instância separada do DataContext cada vez que chamo o serviço que está lançando o erro. Estou tendo um momento muito difícil de descobrir qual é o problema aqui e realmente apreciaria qualquer orientação e/ou explicação sobre o que está acontecendo. Obrigada.

* Editar: **

 [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

Os métodos mencionados são:

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

Tudo o que a classe de serviço de sessão faz é ligar para o sqlxmlsessionStore.UpDatesession (Sessão) se a sessão estiver no banco de dados e ativo, ou sqlxmlsessionstore.insertSession (Sessão) se a solicitação for nova e o ID da sessão estiver ausente ou exclusivo.

Tentei criar uma nova instância do DataContext cada vez que fazia um submitchanges (), mas isso resultou em não ter um objeto de conexão, mesmo quando puxei o mesmo conn. string de configurações. Isso poderia ter algo a ver com minha máquina local?

Ok, então fiz algo que está funcionando, mas não tenho certeza se haverá um problema com isso que não estou prevendo.

Eu só permito que o DataContext envie uma vez. Consegui isso alterando o código submitchanges () para:

    private bool _canSubmit = true;

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

Isso ainda parece uma maneira muito muito hacky para que isso funcione, e eu gostaria de chegar ao fundo do problema, por isso, informe se alguém tiver alguma idéia de como consertar isso.

Foi útil?

Solução 2

Não haveria como saber disso no meu post, mas encontrei o problema. Configurei a injeção de dependência em um httpmodule e houve um bloqueio na função de configuração. Eu acho que estava lá do código antigo que copiei (e depois esqueci) de algum lugar quando eu estava aprendendo a usar o StructureMap pela primeira vez. Eu removi a fechadura e funcionou. (Bem, pelo menos começou a gerar erros novos e não relacionados).

Ah, e a razão pela qual estava afetando meu DataContext foi porque as classes que envolviam instâncias do Datacontext estavam dentro da fechadura.

Outras dicas

Você não pode alterar o conjunto de alterações dentro de submitchanges e não pode ligar para submitanges nos métodos substituídos das classes parciais. Suspeito que você esteja fazendo isso, mas não sigo completamente seus fragmentos de código.

EDITAR

Não entendo como a vida inteira do DataContext está sendo gerenciada. Na primeira parte da pergunta, você diz

Estou criando uma instância separada do datacontext cada vez que chamo o serviço

Mas na segunda parte você diz

Tentei criar uma nova instância do datacontext cada vez que fazia um submitchanges (), mas isso resultou em que eu não teria um objeto de conexão

A próxima coisa que não entendo é como o seu método alterado que chama os submitchanges só funciona, pois descarta quaisquer alterações nos dados feitos após sua primeira chamada devem estar registrando todos os seus dados ou qualquer chamada após a primeira chamada Não é necessário enviar alterações.

Os métodos de instância do datacontext não são seguros, você não pode colocá -lo em uma variável global na inicialização do aplicativo (você está fazendo isso?); Você geralmente deseja um novo DataContext para cada solicitação HTTP, que você pode fazer usando uma estrutura de inversão da estrutura de controle ou apenas no código, novo o dataconext no início da solicitação e envie alterações no final.

Outra técnica é usar vários datacontexts, criar o DataContext, fazer as alterações, enviar chamadas, descartar o DataContext, é muito leve. Muitas vezes, você não precisa ligar para enviar alterações mais de uma vez, a única vez que fiz isso é controlar a ordem de execução das instruções SQL.

Seria bom se você pudesse construir um exemplo mínimo e postar o código inteiro.

Eu sugiro que você anexe um depurador e pegue a exceção no ato. A partir daí, você deve ser capaz de rastrear de onde vem.

Como alternativa, substitua SubmitChanges e registre o StackTrace em Ever Call para rastrear o original do erro.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top