Eu tenho explorado diferentes métodos de edição / atualização de um registro no Entity Framework 5 em um ambiente ASP.NET MVC3, mas até agora nenhum deles marque todas as caixas necessárias. Eu vou explicar o porquê.
Encontrei três métodos aos quais mencionarei os prós e os contras:
Método 1 - Carregar registro original, atualizar cada propriedade
var original = db.Users.Find(updatedUser.UserId);
if (original != null)
{
original.BusinessEntityId = updatedUser.BusinessEntityId;
original.Email = updatedUser.Email;
original.EmployeeId = updatedUser.EmployeeId;
original.Forename = updatedUser.Forename;
original.Surname = updatedUser.Surname;
original.Telephone = updatedUser.Telephone;
original.Title = updatedUser.Title;
original.Fax = updatedUser.Fax;
original.ASPNetUserId = updatedUser.ASPNetUserId;
db.SaveChanges();
}
Prós
- Pode especificar quais propriedades são alteradas
- As visualizações não precisam conter todas as propriedades
Contras
- 2 x consultas no banco de dados para carregar o original e atualizá-lo
Método 2 - Carregar registro original, definir valores alterados
var original = db.Users.Find(updatedUser.UserId);
if (original != null)
{
db.Entry(original).CurrentValues.SetValues(updatedUser);
db.SaveChanges();
}
Prós
- Somente propriedades modificadas são enviadas ao banco de dados
Contras
- As visualizações precisam conter todas as propriedades
- 2 x consultas no banco de dados para carregar o original e atualizá-lo
Método 3 - Anexe o registro atualizado e defina o estado como EntityState.Modified
db.Users.Attach(updatedUser);
db.Entry(updatedUser).State = EntityState.Modified;
db.SaveChanges();
Prós
- 1 x consulta no banco de dados para atualizar
Contras
- Não é possível especificar quais propriedades são alteradas
- As visualizações devem conter todas as propriedades
Questão
Minha pergunta para vocês; existe uma maneira limpa de atingir esse conjunto de metas?
- Pode especificar quais propriedades são alteradas
- As visualizações não precisam conter todas as propriedades (como senha!)
- 1 x consulta no banco de dados para atualizar
Entendo que isso é uma coisa muito pequena a ser destacada, mas posso estar perdendo uma solução simples para isso. Caso contrário, prevalecerá o método ;-)
fonte
Respostas:
Você está procurando:
fonte
Eu realmente gosto da resposta aceita. Eu acredito que há ainda outra maneira de abordar isso também. Digamos que você tenha uma lista muito curta de propriedades que você nunca desejaria incluir em uma Visualização, portanto, ao atualizar a entidade, elas seriam omitidas. Digamos que esses dois campos sejam Senha e SSN.
Este exemplo permite que você essencialmente deixe sua lógica de negócios em paz após adicionar um novo campo à sua tabela Usuários e à sua Visualização.
fonte
fonte
Eu adicionei um método de atualização extra à minha classe base do repositório que é semelhante ao método de atualização gerado pelo Scaffolding. Em vez de definir o objeto inteiro como "modificado", ele define um conjunto de propriedades individuais. (T é um parâmetro genérico de classe.)
E depois ligar, por exemplo:
Eu gosto de uma viagem ao banco de dados. Provavelmente é melhor fazer isso com os modelos de visualização, para evitar repetir conjuntos de propriedades. Ainda não fiz isso porque não sei como evitar trazer as mensagens de validação dos validadores de modelo de exibição para o meu projeto de domínio.
fonte
fonte
set
parte da instrução de atualização.Apenas para adicionar à lista de opções. Você também pode pegar o objeto no banco de dados e usar uma ferramenta de mapeamento automático como o Mapeador Automático para atualizar as partes do registro que deseja alterar.
fonte
Dependendo do seu caso de uso, todas as soluções acima se aplicam. Isto é como eu costumo fazê-lo no entanto:
Para código do lado do servidor (por exemplo, um processo em lote), normalmente carrego as entidades e trabalho com proxies dinâmicos. Geralmente, em processos em lote, você precisa carregar os dados de qualquer maneira no momento em que o serviço é executado. Tento carregar em lote os dados em vez de usar o método find para economizar tempo. Dependendo do processo, eu uso controle de simultaneidade otimista ou pessimista (eu sempre uso otimista, exceto em cenários de execução paralela em que preciso bloquear alguns registros com instruções sql simples, isso é raro). Dependendo do código e do cenário, o impacto pode ser reduzido para quase zero.
Para cenários do lado do cliente, você tem algumas opções
Use modelos de vista. Os modelos devem ter uma propriedade UpdateStatus (não modificado-inserido-atualizado-excluído). É de responsabilidade do cliente definir o valor correto para esta coluna, dependendo das ações do usuário (inserir-atualizar-excluir). O servidor pode consultar os valores originais no banco de dados ou o cliente deve enviar os valores originais ao servidor junto com as linhas alteradas. O servidor deve anexar os valores originais e usar a coluna UpdateStatus para cada linha para decidir como lidar com os novos valores. Nesse cenário, eu sempre uso simultaneidade otimista. Isso fará apenas as instruções insert - update - delete e não nenhuma seleção, mas pode ser necessário algum código inteligente para percorrer o gráfico e atualizar as entidades (depende do seu cenário - aplicativo). Um mapeador pode ajudar, mas não lida com a lógica CRUD
Use uma biblioteca como breeze.js que oculte grande parte dessa complexidade (conforme descrito em 1) e tente ajustá-la ao seu caso de uso.
Espero que ajude
fonte