Estou usando o Entity Framework para preencher um controle de grade. Às vezes, quando faço atualizações, recebo o seguinte erro:
A instrução de atualização, inserção ou exclusão de armazenamento afetou um número inesperado de linhas (0). As entidades podem ter sido modificadas ou excluídas desde que as entidades foram carregadas. Atualize as entradas do ObjectStateManager.
Não consigo descobrir como reproduzir isso. Mas pode ter algo a ver com o quão próximos eu faço as atualizações. Alguém viu isso ou alguém sabe a que a mensagem de erro se refere?
Edit: Infelizmente, não tenho mais liberdade para reproduzir o problema que estava tendo aqui, porque me afastei deste projeto e não me lembro se encontrei uma solução, se outro desenvolvedor a corrigiu ou se eu trabalhei em torno dela. Portanto, não posso aceitar nenhuma resposta.
fonte
Request.Uri
para ver o URL de solicitação real. No meu caso, eu tinha uma lógica de rastreamento que estava atingindo meu site e carregando desnecessariamente o contexto do banco de dados (e ocasionalmente atualizando-o também). Então a página em que eu estava depurando teve seus dados gravados por uma lógica estúpida de código de rastreamento.Respostas:
Esse é um efeito colateral de um recurso chamado simultaneidade otimista.
Não tenho 100% de certeza de como ativá-lo / desativá-lo no Entity Framework, mas basicamente o que está dizendo é que, quando você retirou os dados do banco de dados e quando salvou as alterações, alguém alterou os dados (o que significava quando você foi para salvá-lo, 0 linhas foram atualizadas). Em termos de SQL,
update
awhere
cláusula de sua consulta contém o valor original de todos os campos da linha e, se 0 linhas forem afetadas, ele saberá que algo deu errado.A idéia por trás disso é que você não substituirá uma alteração que seu aplicativo não sabia que aconteceu - é basicamente uma pequena medida de segurança lançada pelo .NET em todas as suas atualizações.
Se for consistente, é provável que esteja acontecendo dentro de sua própria lógica (por exemplo, você está atualizando os dados por outro método entre o select e a atualização), mas pode ser simplesmente uma condição de corrida entre dois aplicativos.
fonte
Eu me deparei com isso e foi causado pelo campo de ID (chave) da entidade não estar definido. Portanto, quando o contexto foi salvar os dados, não foi possível encontrar um ID = 0. Certifique-se de colocar um ponto de interrupção na sua declaração de atualização e verifique se o ID da entidade foi definido.
Do comentário de Paul Bellora
fonte
Uau, muitas respostas, mas recebi esse erro quando fiz algo ligeiramente diferente que ninguém mais mencionou.
Para encurtar a história, se você criar um novo objeto e informar à EF que ela foi modificada usando o
EntityState.Modified
comando, ele emitirá esse erro, pois ainda não existe no banco de dados. Aqui está o meu código:Sim, isso parece idiota, mas surgiu porque o método em questão costumava ter
foo
passado para ele tendo sido criado anteriormente, agora sósomeValue
passou para ele e se criafoo
.Reparo fácil, basta mudar
EntityState.Modified
paraEntityState.Added
ou alterar essa linha inteira para:fonte
Eu estava enfrentando esse mesmo erro assustador ... :) Então eu percebi que estava esquecendo de definir um
@Html.HiddenFor(model => model.UserProfile.UserId)
para a chave primária do objeto que está sendo atualizado! Costumo esquecer essa coisa simples, mas muito importante!
A propósito:
HiddenFor
é para o ASP.NET MVC.fonte
UserId
na forma, muito propenso a hackers ... isso deve ser preenchida depois deHttpContext.Current.User.Identity.Name
HiddenFor
que quero dizer é que, mesmo armazenando isso, você precisará obtê-lo deHttpContext
qualquer maneira ... Eu não colocaria essa propriedade no formulário, o que me forçaria a sempre preenchê-la no lado do servidor ...Verifique se você esqueceu o atributo "DataKeyNames" no GridView. é uma obrigação ao modificar dados no GridView
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.datakeynames.aspx
fonte
O problema é causado por uma de duas coisas: -
Concurrency Mode: Fixed
.. e a simultaneidade otimista impediu que os dados fossem salvos. Ou seja. alguns alteraram os dados da linha entre o momento em que você recebeu os dados do servidor e quando os salvou.StoreGeneratedPattern = Computed
) e essa linha não existe.fonte
Eu recebi esse mesmo erro porque parte da PK era uma coluna de data e hora e o registro sendo inserido usava DateTime.Now como o valor dessa coluna. A estrutura da entidade inseria o valor com precisão de milissegundos e, em seguida, procurava o valor que acabou de inserir também com precisão de milissegundos. No entanto, o SqlServer arredondou o valor para a segunda precisão e, portanto, a estrutura da entidade não conseguiu encontrar o valor de precisão em milissegundos.
A solução foi truncar os milissegundos de DateTime.Now antes de inserir.
fonte
Date
coluna com umDateTime
valorEu estava com o mesmo problema e a resposta da @ webtrifusion ajudou a encontrar a solução.
Meu modelo estava usando o
Bind(Exclude)
atributo no ID da entidade que estava causando o valor do ID da entidade ser zero no HttpPost.fonte
Eu tive o mesmo problema, acho que foi causado pelo RowVersion que era nulo. Verifique se seu ID e sua RowVersion não são nulos .
para mais informações, consulte este tutorial
http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application
fonte
Comecei a receber esse erro depois de mudar do modelo primeiro para o primeiro código. Eu tenho vários threads atualizando um banco de dados onde alguns podem atualizar a mesma linha. Não sei por que não tive um problema ao usar o modelo primeiro, suponha que ele use um padrão de simultaneidade diferente.
Para lidar com isso em um local sabendo as condições sob as quais isso pode ocorrer, adicionei a seguinte sobrecarga à minha classe DbContext:
Em seguida, chamado
SaveChanges(true)
sempre que aplicável.fonte
Você precisa incluir explicitamente um BoundField da chave primária. Se você não deseja que o usuário veja a chave primária, é necessário ocultá-la via css:
Onde 'hidden' é uma classe em css cuja exibição é definida como 'none'.
fonte
Durante a edição, inclua o ID ou a chave primária da entidade como um campo oculto na exibição
ie
isso resolve o problema.
Além disso, se o seu modelo incluir itens não utilizados, inclua-o também e publique-o no controlador
fonte
Eu também me deparei com esse erro. O problema foi causado por um gatilho na mesa que eu estava tentando salvar. O gatilho usou 'INSTEAD OF INSERT', o que significa que 0 linhas já foram inseridas nessa tabela, daí o erro. Felizmente, no caso de a funcionalidade do gatilho estar incorreta, mas acho que poderia ser uma operação válida que, de alguma forma, deveria ser manipulada no código. Espero que isso ajude alguém um dia.
fonte
SELECT SCOPE_IDENTITY() as MyViewId
Me deparei com esse problema em uma tabela em que faltava uma chave primária e tinha uma coluna DATETIME (2, 3) (portanto, a "chave primária" da entidade era uma combinação de todas as colunas) ... Ao executar a inserção, o carimbo de data e hora tinha um horário mais preciso (2018-03-20 08: 29: 51.8319154) que foi truncado para (2018-03-20 08: 29: 51.832) para que a pesquisa nos campos-chave falhe.
fonte
Eu também tive esse erro. Existem algumas situações em que a Entidade pode não estar ciente do Contexto de Banco de Dados real que você está usando ou o Modelo pode ser diferente. Para isso, defina: EntityState.Modified; para EntityState.Added;
Para fazer isso:
Isso garantirá que a Entidade saiba que você está usando ou adicionando o Estado com o qual está trabalhando. Nesse ponto, todos os valores de modelo corretos precisam ser definidos. Cuidado para não perder nenhuma alteração que possa ter sido feita em segundo plano.
Espero que isto ajude.
fonte
Minha versão de linha era nula, então tive que adicionar isso à exibição que resolveu meu problema
fonte
A linha
[DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.None)]
fez o truque no meu caso:fonte
Apenas certifique-se de que a tabela e o formulário tenham a chave primária e o edmx atualizados.
Descobri que os erros durante a atualização geralmente eram devidos a: - Nenhuma chave primária na tabela - Nenhuma chave primária na visualização / formulário Editar (por exemplo
@Html.HiddenFor(m=>m.Id
)fonte
Eu tive o mesmo problema. No meu caso, eu estava tentando atualizar a chave primária, o que não é permitido.
fonte
Eu recebi esse erro esporadicamente ao usar um
async
método. Não aconteceu desde que mudei para um método síncrono.Erros esporadicamente:
Funciona o tempo todo:
fonte
Eu recebi esse erro quando estava excluindo algumas linhas no banco de dados (no loop) e adicionando as novas na mesma tabela.
As soluções para mim foram: criar dinamicamente um novo contexto em cada iteração de loop
fonte
fonte
Isso também acontecerá se você estiver tentando inserir em uma situação de restrição única, ou seja, se você puder ter apenas um tipo de endereço por empregador e tentar inserir um segundo desse mesmo tipo com o mesmo empregador, obterá o mesmo problema .
OU
Isso também poderia acontecer se todas as propriedades do objeto às quais foram atribuídas fossem atribuídas com os mesmos valores que tinham antes.
fonte
Se você estiver tentando criar mapeamento no seu arquivo edmx para uma "função Importação", isso pode resultar neste erro. Apenas limpe os campos para inserir, atualizar e excluir localizados em Detalhes do mapeamento para uma determinada entidade em seu edmx, e deve funcionar. Espero ter deixado claro.
fonte
Eu recebi essa exceção ao anexar um objeto que não existia no banco de dados. Eu assumi que o objeto foi carregado de um contexto separado, mas se foi a primeira vez que o usuário visitou o site, o objeto foi criado do zero. Temos chaves primárias de incremento automático, para que eu possa substituir
com
fonte
Bem, eu tenho esse mesmo problema. Mas isso foi devido ao meu próprio erro. Na verdade, eu estava salvando um objeto em vez de adicioná-lo. Então esse foi o conflito.
fonte
Uma maneira de depurar esse problema em um ambiente do Sql Server é usar o Sql Profiler incluído na sua cópia do SqlServer ou, se usar a versão Express, obtenha uma cópia do Express Profiler gratuitamente no CodePlex, seguindo o link abaixo:
Express Profiler
Usando o Sql Profiler, você pode acessar o que estiver sendo enviado pela EF ao banco de dados. No meu caso, isso equivale a:
Copiei colei isso em uma janela de consulta no Sql Server e o executei. Com certeza, embora tenha sido executado, 0 registros foram afetados por esta consulta, portanto, o erro está sendo retornado pelo EF.
No meu caso, o problema foi causado pelo CategoryID.
Não houve um ID da categoria identificado pelo ID EF enviado ao banco de dados, portanto, 0 registro foi afetado.
Porém, isso não foi culpa da EF, mas sim um coalescente nulo de buggy "??" em um View Controller que estava enviando bobagens para a camada de dados.
fonte
Nenhuma das respostas acima cobriu completamente minha situação e a solução para ela.
Código em que o erro foi gerado no controlador MVC5:
Eu recebi essa exceção quando estava salvando um objeto em uma exibição Editar. O motivo pelo qual foi lançado foi porque, quando voltei para salvá-lo, havia modificado as propriedades que formavam a chave primária no objeto. Portanto, definir seu estado como Modificado não fazia sentido para a EF - era uma nova entrada, não uma salva anteriormente.
Você pode resolver isso usando A) modificando a chamada de salvar para Adicionar o objeto ou B) apenas não alterando a chave primária na edição. Eu fiz B).
fonte
Quando a resposta aceita disse " ela não substituirá uma alteração que seu aplicativo não sabia que aconteceu ", fiquei cético porque meu objeto foi criado recentemente. Mas acontece que havia um
INSTEAD OF UPDATE, INSERT- TRIGGER
anexo à tabela que estava atualizando uma coluna calculada da mesma tabela.Depois que mudei para
AFTER INSERT, UPDATE
, estava funcionando bem.fonte
Isso aconteceu comigo devido a uma incompatibilidade entre datetime e datetime2. Estranhamente, funcionou bem antes de um testador descobrir o problema. O modelo My Code First incluiu um DateTime como parte da chave primária:
A coluna gerada é uma coluna de data e hora. Ao chamar SaveChanges, o EF gerou o seguinte SQL:
Como estava tentando corresponder uma coluna datetime com um valor datetime2, ele não retornou resultados. A única solução em que consegui pensar foi alterar a coluna para um datetime2:
fonte
datetime
vs.datetime2
. Essencialmente, alguns valores de milissegundos serão avaliados para uma correspondência, outros não. O mesmo aconteceu comigo e eu também mudei paraDateTime2
.