Estou tentando atualizar o registro usando o EF6. Primeiro localizando o registro, se existir, atualize-o. Aqui está o meu código: -
var book = new Model.Book
{
BookNumber = _book.BookNumber,
BookName = _book.BookName,
BookTitle = _book.BookTitle,
};
using (var db = new MyContextDB())
{
var result = db.Books.SingleOrDefault(b => b.BookNumber == bookNumber);
if (result != null)
{
try
{
db.Books.Attach(book);
db.Entry(book).State = EntityState.Modified;
db.SaveChanges();
}
catch (Exception ex)
{
throw;
}
}
}
Sempre que tento atualizar o registro usando o código acima, estou recebendo este erro: -
{System.Data.Entity.Infrastructure.DbUpdateConcurrencyException: a declaraçã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. Atualizar entrada do ObjectStateManager
c#
entity-framework
entity-framework-6
ef-database-first
user1327064
fonte
fonte
catch (Exception ex){throw;}
é redundante e você pode removê-lo completamente.Respostas:
Você está tentando atualizar o registro (o que para mim significa "alterar um valor em um registro existente e salvá-lo"). Portanto, você precisa recuperar o objeto, fazer uma alteração e salvá-lo.
fonte
db.SaveChanges()
com objetos modificados no contexto atualiza o banco de dados.SaveChanges
o contexto, avalia todos os objetos que está rastreando para determinar se eles foram adicionados, alterados ou excluídos e emite o SQL apropriado no banco de dados conectado.Estive revisando o código-fonte do Entity Framework e encontrei uma maneira de realmente atualizar uma entidade se você conhecer a propriedade Key:
Caso contrário, verifique o implementação AddOrUpdate para obter idéias.
Espero que esta ajuda!
fonte
SaveChanges()
chamada seja necessária após a definição dos valores.Você pode usar o
AddOrUpdate
método:fonte
.AddOrUpdate()
é usado durante a migração do banco de dados, é altamente desencorajado usar esse método fora das migrações, por isso, está noEntity.Migrations
espaço para nome.AddOrUpdate()
método é destinado a migrações e não é adequado para situações em que você precisa apenas atualizar a linha existente. Caso você não tenha um livro com referência de pesquisa (ou seja, ID), ele criará uma nova linha e poderá ser um problema nos próximos casos (por exemplo, você terá uma API que precisará retornar sua resposta 404-NotFound se você tente chamar o método PUT para a linha inexistente).Então você tem uma entidade que é atualizada e deseja atualizá-la no banco de dados com a menor quantidade de código ...
A simultaneidade é sempre complicada, mas suponho que você deseja que suas atualizações sejam vencidas. Aqui está como eu fiz isso no meu mesmo caso e modifiquei os nomes para imitar suas aulas. Em outras palavras, basta mudar
attach
paraadd
e funciona para mim:fonte
Você deve usar o método Entry () para atualizar todos os campos do seu objeto. Lembre-se também de que você não pode alterar o ID do campo (chave); portanto, primeiro defina o ID para o mesmo que você edita.
fonte
Esse código é o resultado de um teste para atualizar apenas um conjunto de colunas sem fazer uma consulta para retornar o registro primeiro. Ele usa o código do Entity Framework 7 primeiro.
Aqui está o código completo:
fonte
Para o núcleo .net
fonte
Aqui está a melhor solução para esse problema: No modo de exibição, adicione todo o ID (chaves). Considere ter várias tabelas nomeadas (Primeira, Segunda e Terceira)
No código C #,
fonte
Attach
uma entidade definirá seu estado de rastreamento paraUnchanged
. Para atualizar uma entidade existente, basta definir o estado de rastreamento paraModified
. De acordo com os documentos EF6 :fonte
fonte
Eu encontrei uma maneira que funciona muito bem.
fonte
Você deve remover
db.Books.Attach(book);
fonte
Aqui está o meu método de atualização de entidade pós-RIA (para o período Ef6):
Observe que
FrameworkTypeUtility.SetProperties()
é uma pequena função utilitária que escrevi muito antes do AutoMapper no NuGet:fonte
Como Renat disse, remova:
db.Books.Attach(book);
Além disso, altere sua consulta de resultado para usar "AsNoTracking", porque esta consulta está descartando o estado do modelo da estrutura da entidade. Ele acha que "resultado" é o livro para rastrear agora e você não quer isso.
fonte
Tente....
UpdateModel (livro);
fonte
Eu sei que já foi respondido algumas vezes, mas eu gosto abaixo da maneira de fazer isso. Espero que ajude alguém.
fonte
Isso se for para o Entity Framework 6.2.0.
Se você tiver um
DbSet
item específico e um que precise ser atualizado ou criado:No entanto, isso também pode ser usado para um genérico
DbSet
com uma única chave primária ou uma chave primária composta.fonte