update lista con actualizar c# asp.net linq linq-to-sql datacontext

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.