lista - update linq c# list
La manera más eficiente de actualizar con LINQ to SQL (6)
No puede adjuntar una entidad modificada a un DataContext cuando no hay una columna RowVersion. En su lugar, puede almacenar la entidad original en su aplicación siempre que mantenga una copia para los cambios de datos. Luego, cuando los cambios deben ser guardados, puede adjuntar la entidad original a un DataContext, cambiar sus valores para que coincidan con los valores modificados de la entidad y enviar los cambios.
Aquí hay un ejemplo:
public int updateEmployee(App3_EMPLOYEE employee, App3_EMPLOYEE originalEmployee)
{
DBContextDataContext db = new DBContextDataContext();
db.App3_EMPLOYEEs.Attach(originalEmployee);
// TODO: Copy values from employee to original employee
db.SubmitChanges();
return employee.PKEY;
}
Actualizar:
Hay una tabla en la base de datos con columnas ID, Nombre, Notas
// fetch an employee which will not be changed in the application
Employee original;
using(var db = new TestDbDataContext())
{
original = db.Employees.First(e => e.ID == 2);
}
// create an instance to work with
var modified = new Employee {ID = original.ID, Name = original.Name, Notes = original.Notes};
// change some info
modified.Notes = string.Format("new notes as of {0}", DateTime.Now.ToShortTimeString());
// update
using(var db = new TestDbDataContext())
{
db.Employees.Attach(original);
original.Notes = modified.Notes;
db.SubmitChanges();
}
¿Puedo actualizar mi registro de empleado como figura en la siguiente función o tengo que hacer una consulta de la colección de empleados primero y luego actualizar los datos?
public int updateEmployee(App3_EMPLOYEE employee)
{
DBContextDataContext db = new DBContextDataContext();
db.App3_EMPLOYEEs.Attach(employee);
db.SubmitChanges();
return employee.PKEY;
}
¿O tengo que hacer lo siguiente?
public int updateEmployee(App3_EMPLOYEE employee)
{
DBContextDataContext db = new DBContextDataContext();
App3_EMPLOYEE emp = db.App3_EMPLOYEEs.Single(e => e.PKEY == employee.PKEY);
db.App3_EMPLOYEEs.Attach(employee,emp);
db.SubmitChanges();
return employee.PKEY;
}
Pero no quiero usar la segunda opción. ¿Hay alguna forma eficiente de actualizar los datos?
Estoy obteniendo este error al usar ambas formas:
Se ha intentado adjuntar o agregar una entidad que no sea nueva, que tal vez se haya cargado desde otro DataContext. Esto no es compatible.
Hay una discusión sobre este tema aquí en MSDN. Te recomendamos usar un campo IsVersion y el método Attach.
Puede adjuntar una entidad modificada no adjunta, mediante el uso de esta sobrecarga:
db.App3_EMPLOYEEs.Attach(employee, true);//Attach as modfieied
Tenga en cuenta que para que esto funcione, necesita en su tabla una columna de "Versión" de tipo "marca de tiempo"
Encuentro el siguiente trabajo alrededor de este problema:
1) buscar y actualizar la entidad (voy a utilizar de esta manera porque está bien para mí)
public int updateEmployee(App3_EMPLOYEE employee)
{
AppEmployeeDataContext db = new AppEmployeeDataContext();
App3_EMPLOYEE emp = db.App3_EMPLOYEEs.Single(e => e.PKEY == employee.PKEY);
emp.FIRSTNAME = employee.FIRSTNAME;//copy property one by one
db.SubmitChanges();
return employee.PKEY;
}
2) deshabilitar ObjectTrackingEnabled como sigue
// but in this case lazy loading is not supported
public AppEmployeeDataContext() :
base(global::LinqLibrary.Properties.Settings.Default.AppConnect3DBConnectionString, mappingSource)
{
this.ObjectTrackingEnabled = false;
OnCreated();
}
3) Separar todos los objetos relacionados
partial class App3_EMPLOYEE
{
public void Detach()
{
this._APP3_EMPLOYEE_EXTs = default(EntityRef<APP3_EMPLOYEE_EXT>);
}
}
public int updateEmployee(App3_EMPLOYEE employee)
{
AppEmployeeDataContext db = new AppEmployeeDataContext();
employee.Detach();
db.App3_EMPLOYEEs.Attach(employee,true);
db.SubmitChanges();
return employee.PKEY;
}
4) use la marca de tiempo en la columna
http://www.west-wind.com/weblog/posts/135659.aspx
5) Cree un procedimiento almacenado para actualizar sus datos y llámelo por contexto de base de datos
Esta es una función en mi clase de Repositorio que uso para actualizar entidades
protected void Attach(TEntity entity)
{
try
{
_dataContext.GetTable<TEntity>().Attach(entity);
_dataContext.Refresh(RefreshMode.KeepCurrentValues, entity);
}
catch (DuplicateKeyException ex) //Data context knows about this entity so just update values
{
_dataContext.Refresh(RefreshMode.KeepCurrentValues, entity);
}
}
Donde TEntity es su clase de base de datos y, dependiendo de su configuración, es posible que desee hacer
_dataContext.Attach(entity);
Use este método extendido para actualizar todas las propiedades que son atributos de columna:
public static void SaveToOriginal<T>(this T original, T actual)
{
foreach (var prop in typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Where(info => info.GetCustomAttribute<System.Data.Linq.Mapping.ColumnAttribute>() != null))
{
prop.SetValue(original, prop.GetValue(actual));
}
}
Quiero decir, primero recuperas el original de la base de datos, usas el método para mapear todos los atributos de las columnas desde un nuevo elemento hasta el original y, finalmente, haces un envío. Espero que esto ayude.