Estados de objeto y control de cambios (LINQ to SQL)
Actualización: November 2007
Los objetos de LINQ to SQL siempre participan en algún estado. Por ejemplo, cuando LINQ to SQL crea un nuevo objeto, el objeto está en estado Unchanged. Un objeto nuevo que ha creado es desconocido para DataContext y su estado es Untracked. Después de la ejecución correcta de SubmitChanges, todos los objetos que LINQ to SQL reconoce están en estado Unchanged. (La única excepción son los objetos que se han eliminado correctamente de la base de datos, que están en estado Deleted y no se pueden utilizar en esa instancia de DataContext.)
Estados de objeto
La tabla siguiente enumera los posibles estados de los objetos de LINQ to SQL.
Estado |
Descripción |
---|---|
Untracked |
Objeto del que LINQ to SQL no realiza un seguimiento. Algunos ejemplos son:
|
Unchanged |
Un objeto recuperado utilizando el DataContext actual y que se desconoce si se ha modificado desde que se creó. |
PossiblyModified |
Objeto asociado a un DataContext. Para obtener más información, vea Recuperación de datos y operaciones CUD en aplicaciones de niveles N (LINQ to SQL). |
ToBeInserted |
Objeto no recuperado utilizando el DataContext actual. Esto produce una operación INSERT en la base de datos durante la ejecución de SubmitChanges. |
ToBeUpdated |
Objeto que se sabe que se modificó desde que se recuperó. Esto produce una operación UPDATE en la base de datos durante la ejecución de SubmitChanges. |
ToBeDeleted |
Objeto marcado para la eliminación, que produce una operación DELETE en la base de datos durante la ejecución de SubmitChanges. |
Deleted |
Objeto eliminado de la base de datos. Este estado es definitivo y no permite transiciones adicionales. |
Insertar objetos
Puede solicitar Inserts explícitamente mediante el método InsertOnSubmit. Como alternativa, LINQ to SQL puede deducir los elementos Inserts mediante la búsqueda de los objetos conectados a uno de los objetos conocidos que deben actualizarse. Por ejemplo, si agrega un objeto Untracked a EntitySet<TEntity> o establece EntityRef<TEntity> en un objeto Untracked, hace que se pueda obtener acceso al objeto Untracked por medio de los objetos del gráfico de los que se realiza un seguimiento. Durante el procesamiento de SubmitChanges, LINQ to SQL recorre los objetos de los que se realiza un seguimiento y detecta cualquier objeto persistente accesible del que no se realiza un seguimiento. Tales objetos son candidatos para la inserción en la base de datos.
Para las clases de una jerarquía de herencia, InsertOnSubmit(o) establece también el valor del miembro designado como discriminador para que coincida con el tipo del objeto o. Si un tipo que coincide con el valor de discriminador predeterminado, esta acción hace que dicho valor se sobrescriba con el valor predeterminado. Para obtener más información, consulte Compatibilidad con la herencia (LINQ to SQL).
Nota importante: |
---|
Un objeto agregado a Table no se encuentra en la memoria caché de identidad. La memoria caché de identidad sólo refleja lo que se recupera de la base de datos. Después de una llamada a InsertOnSubmit, la entidad agregada no aparece en las consultas en la base de datos hasta que se complete SubmitChanges correctamente. |
Eliminar objetos
Un objeto o del que se realiza un seguimiento se marca para la eliminación mediante una llamada a DeleteOnSubmit(o) en el objeto Table<TEntity> adecuado. LINQ to SQL considera la eliminación de un objeto de EntitySet<TEntity> como una operación de actualización y el valor de clave externa correspondiente se establece en null. El destino de la operación (o) no se elimina de su tabla. Por ejemplo, cust.Orders.DeleteOnSubmit(ord) indica una actualización donde la relación entre cust y ord se rompe estableciendo la clave externa ord.CustomerID en null. Esto no produce la eliminación de la fila que corresponde a ord.
LINQ to SQL realiza el procesamiento siguiente cuando se elimina un objeto (DeleteOnSubmit) de su tabla:
Cuando se llama a SubmitChanges, se realiza una operación DELETE para ese objeto.
La eliminación no se propaga a los objetos relacionados, estén cargados o no. Concretamente, los objetos relacionados no se cargan para actualizar la propiedad de la relación.
Después de la ejecución correcta de SubmitChanges, los objetos se establecen en el estado Deleted. Como resultado, no se puede utilizar el objeto ni su id en DataContext. La memoria caché interna mantenida por una instancia de DataContext no elimina los objetos que se recuperan o que se agregan como nuevos, incluso una vez eliminados de la base de datos.
Sólo se puede llamar a DeleteOnSubmit en un objeto del que DataContext realiza un seguimiento. Para un objeto Untracked, se debe llamar a Attach antes de llamar a DeleteOnSubmit. Si se llama a DeleteOnSubmit en un objeto Untracked, se inicia una excepción.
Nota: |
---|
Al quitar un objeto de una tabla, se indica a LINQ to SQL que genere un comando SQL DELETE correspondiente en el momento de ejecutar el método SubmitChanges. Esta acción no quita el objeto de la memoria caché ni propaga la eliminación a los objetos relacionados. Para reclamar el id de un objeto eliminado, utilice una nueva instancia de DataContext. Para la limpieza de los objetos relacionados, puede utilizar la característica de eliminación en cascada de la base de datos, o eliminar los objetos relacionados manualmente. Los objetos relacionados no tienen que eliminarse en ningún orden especial (a diferencia de lo que sucede en la base de datos). |
Actualizar objetos
Las Updates se detectan observando las notificaciones de cambios. Las notificaciones se proporcionan a través del evento PropertyChanging en los establecedores de propiedades. Cuando LINQ to SQL recibe una notificación del primer cambio de un objeto, crea una copia del mismo y lo considera como candidato para generar una instrucción Update.
Para los objetos que no implementan INotifyPropertyChanging, LINQ to SQL mantiene una copia de los valores que tenían los objetos la primera vez que se materializaron. Al llamar a SubmitChanges, LINQ to SQL compara los valores originales y actuales para decidir si se ha cambiado el objeto.
Para las actualizaciones de relaciones, la autoridad es la referencia del elemento secundario al elemento primario (es decir, la referencia que corresponde a la clave externa). La referencia en dirección inversa (es decir, del elemento primario al elemento secundario) es opcional. Las clases de relaciones (EntitySet<TEntity> y EntityRef<TEntity>) garantizan que las referencias bidireccionales son coherentes para las relaciones uno a varios y uno a uno. Si el modelo de objetos no utiliza EntitySet<TEntity> o EntityRef<TEntity> y si la referencia inversa está presente, es su responsabilidad mantenerla coherente con la referencia adelantada cuando se actualice la relación.
Si actualiza la referencia requerida y la clave externa correspondiente, debe asegurarse de que coinciden. Se producirá una excepción InvalidOperationException si ambas no están sincronizadas cuando se llame a SubmitChanges. Aunque los cambios de los valores de clave externa son suficientes para que se actualice la fila subyacente, debería cambiar la referencia para mantener la conectividad del gráfico de objetos y la coherencia bidireccional de las relaciones.
Vea también
Conceptos
Operaciones de inserción, actualización y eliminación (LINQ to SQL)