2012-07-02 25 views
7

Usando asp.net 4 aunque C#.LINQ to SQL - actualización de registros

En mi capa de acceso a datos tengo métodos para guardar y actualizar registros. Ahorrar es bastante fácil, pero la actualización es tediosa.

Anteriormente utilicé SubSonic, que era genial, ya que tenía registro activo y sabía que si cargaba un registro, cambiaba algunas entradas y luego lo guardaba de nuevo, lo reconocía como una actualización y no intentaba guardar un nuevo entrada en el DB.

No sé cómo hacer lo mismo en LINQ. Como resultado de mi flujo de trabajo es la siguiente:

  1. de las páginas web en juego 'Record A' de la BD
  2. Algunos valores en que se cambian por el usuario.
  3. 'Record A' se devuelve a la capa de acceso a datos
  4. Ahora necesito cargar el Registro A de nuevo, llamándolo 'SavedRecord A', actualizar todos los valores en este objeto con los valores del 'Record A' pasado ¡y luego actualiza/guarda 'SavedRecord A'!

Si acabo de guardar 'Record A' termino con una nueva entrada en la base de datos.

Obviamente, sería más agradable para simplemente pase de grabación A y hacer algo como:

RecordA.Update(); 

estoy presumiendo que hay algo que me falta aquí, pero no puedo encontrar una respuesta directa en línea.

Respuesta

1

Cuando LINQ-to-SQL actualiza un registro en la base de datos, necesita saber exactamente qué campos fueron cambiados para poder actualizarlos. Es, básicamente, tiene tres opciones:

  • Cuando los datos actualizados se devuelve al servidor web, cargar los datos existentes de la base de datos, asignar todas las propiedades al objeto cargado y llame SubmitChanges(). Cualquier propiedad que tenga asignado el valor existente no se actualizará.
  • Mantenga un registro del estado no modificado del objeto y use Attach con los valores sin modificar y modificados.
  • Inicialice un nuevo objeto con todo el estado requerido por la comprobación de concurrencia optimista (si está habilitada, que es por defecto).A continuación, adjunte el objeto y, finalmente, actualice las propiedades modificadas después de la conexión para que el rastreador de cambios de DataContext tenga en cuenta las actualizaciones.

Normalmente utilizo la primera opción, ya que es más fácil. Hay una penalización de rendimiento con dos llamadas a bases de datos, pero a menos que haga muchas actualizaciones, no importará.

+0

Gracias, es sorprendente que no haya una manera más agradable de hacerlo. He estado haciendo el método de 'dos ​​llamadas DB' desde que comencé a usar LINQ to SQL pero siempre he tenido la sensación de que me faltaba una respuesta obviamente más fácil. Parece que no, lo cual es bueno y malo. –

2

que puede lograr lo que desee mediante la Attach method en el Table ejemplo, y comprometerse a través del método de la SubmitChanges()DataContext.

Este proceso puede no ser tan directo como nos gustaría, pero puede leer LINQ to SQL: Updating Entities de David DeWinter para obtener una explicación/tutorial más detallado.

+0

Gracias, lo verificaremos. –

1

digamos que tiene una clase de producto O DB, entonces tendrá que hacer esto.

DbContext _db = new DbContext(); 

    var _product = (from p in _db.Products 
            where p.Id == 1 // suppose you getting the first product 
            select p).First(); // this will fetch the first record. 

    _product.ProductName = "New Product"; 

    _db.SaveChanges(); 

     // this is for EF LINQ to Objects 
    _db.Entry(_product).State = EntityState.Modified; 
    _db.SaveChanges(); 

------------------------------------------------------------------------------------- 
this is another example using Attach 
------------------------------------------------------------------------------------- 

public static void Update(IEnumerable<Sample> samples , DataClassesDataContext db) 
{ 
    db.Samples.AttachAll(samples); 
    db.Refresh(RefreshMode.KeepCurrentValues, samples) 
    db.SubmitChanges(); 
} 

Si conecta sus entidades para el contexto y Actualizar (con KeepCurrentValues ​​seleccionados), LINQ a SQL obtendrá esas entidades desde el servidor, compararlas y marcar actualizado los que son distintos

+0

Gracias, en mi caso, aunque no sabré realmente qué campos han cambiado ya que el usuario hará la edición. Por lo tanto, tengo que asumir que todos los campos han cambiado y escribir la actualización en consecuencia. Es tedioso, pero al menos sé que lo he estado haciendo de la manera "correcta", aunque no me parezca. –

+0

no importa qué campos ha sido editado por el usuario, siempre que pase el modelo al ActionResult en su controlador en el método HTTPPOST y llame a SaveChanges(), todos los registros se actualizan en la base de datos. –

+0

Entonces, ¿es posible hacer que esto funcione cuando el cliente solo ha pasado un único valor cambiado + un campo de referencia de clave? Supongamos que les pasa un registro serializado y devuelven un registro serializado actualizado que contiene solo los dos campos. Hasta ahora, en mis pruebas, LinqToSql acaba de intentar sobrescribir los datos existentes con nulos. Obviamente, esto significa que nunca podrá anular explícitamente un campo que admite nulos. Tratando de evitar escribir mucho de este campo = ese campo. – RoboJ1M