He estado explorando diferentes métodos para editar / actualizar un registro dentro de Entity Framework 5 en un entorno ASP.NET MVC3, pero hasta ahora ninguno de ellos cumple todos los cuadros que necesito. Te explicaré por qué.
He encontrado tres métodos con los cuales mencionaré los pros y los contras:
Método 1 - Cargue el registro original, actualice cada propiedad
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();
}
Pros
- Puede especificar qué propiedades cambian
- Las vistas no necesitan contener todas las propiedades
Contras
- 2 x consultas en la base de datos para cargar el original y luego actualizarlo
Método 2: cargar el registro original, establecer valores modificados
var original = db.Users.Find(updatedUser.UserId);
if (original != null)
{
db.Entry(original).CurrentValues.SetValues(updatedUser);
db.SaveChanges();
}
Pros
- Solo las propiedades modificadas se envían a la base de datos.
Contras
- Las vistas deben contener todas las propiedades
- 2 x consultas en la base de datos para cargar el original y luego actualizarlo
Método 3: adjunte el registro actualizado y establezca el estado en EntityState.Modified
db.Users.Attach(updatedUser);
db.Entry(updatedUser).State = EntityState.Modified;
db.SaveChanges();
Pros
- 1 x consulta en la base de datos para actualizar
Contras
- No se puede especificar qué propiedades cambian
- Las vistas deben contener todas las propiedades
Pregunta
Mi pregunta para ustedes chicos; ¿Hay alguna manera limpia de lograr este conjunto de objetivos?
- Puede especificar qué propiedades cambian
- Las vistas no necesitan contener todas las propiedades (como la contraseña)
- 1 x consulta en la base de datos para actualizar
Entiendo que esto es algo bastante menor para señalar, pero es posible que me falte una solución simple para esto. Si no, el método uno prevalecerá ;-)
fuente
Respuestas:
Estás buscando:
fuente
Realmente me gusta la respuesta aceptada. Creo que hay otra forma de abordar esto también. Supongamos que tiene una lista muy corta de propiedades que no desea incluir en una Vista, por lo que al actualizar la entidad, se omitirán. Digamos que esos dos campos son Contraseña y SSN.
Este ejemplo le permite esencialmente dejar en paz su lógica empresarial después de agregar un nuevo campo a su tabla Usuarios y a su Vista.
fuente
fuente
He agregado un método de actualización adicional en mi clase base de repositorio que es similar al método de actualización generado por Scaffolding. En lugar de configurar todo el objeto como "modificado", establece un conjunto de propiedades individuales. (T es un parámetro genérico de clase).
Y luego llamar, por ejemplo:
Me gusta un viaje a la base de datos. Sin embargo, probablemente sea mejor hacerlo con los modelos de vista para evitar repetir conjuntos de propiedades. Todavía no lo he hecho porque no sé cómo evitar llevar los mensajes de validación de mis validadores de modelos de vista a mi proyecto de dominio.
fuente
fuente
set
parte de la declaración de actualización.Solo para agregar a la lista de opciones. También puede tomar el objeto de la base de datos y usar una herramienta de mapeo automático como Auto Mapper para actualizar las partes del registro que desea cambiar.
fuente
Dependiendo de su caso de uso, se aplican todas las soluciones anteriores. Sin embargo, así es como lo hago habitualmente:
Para el código del lado del servidor (por ejemplo, un proceso por lotes), normalmente cargo las entidades y trabajo con proxys dinámicos. Por lo general, en los procesos por lotes, debe cargar los datos de todos modos en el momento en que se ejecuta el servicio. Intento cargar por lotes los datos en lugar de usar el método find para ahorrar algo de tiempo. Dependiendo del proceso, uso control de concurrencia optimista o pesimista (siempre uso optimista, excepto para escenarios de ejecución paralelos en los que necesito bloquear algunos registros con declaraciones SQL simples, aunque esto es raro). Dependiendo del código y el escenario, el impacto puede reducirse a casi cero.
Para escenarios del lado del cliente, tiene algunas opciones
Usar modelos de vista. Los modelos deben tener una propiedad UpdateStatus (no modificado-insertado-actualizado-eliminado). Es responsabilidad del cliente establecer el valor correcto para esta columna en función de las acciones del usuario (insertar-actualizar-eliminar). El servidor puede consultar a la base de datos los valores originales o el cliente debe enviar los valores originales al servidor junto con las filas modificadas. El servidor debe adjuntar los valores originales y usar la columna UpdateStatus para cada fila para decidir cómo manejar los nuevos valores. En este escenario siempre uso simultaneidad optimista. Esto solo hará las instrucciones de inserción - actualización - eliminación y no ninguna selección, pero puede necesitar un código inteligente para recorrer el gráfico y actualizar las entidades (depende de su escenario - aplicación). Un mapeador puede ayudar pero no maneja la lógica CRUD
Use una biblioteca como breeze.js que oculte la mayor parte de esta complejidad (como se describe en 1) e intente ajustarla a su caso de uso.
Espero eso ayude
fuente