Agregar, modificar y eliminar objetos (Entity Framework)

Los objetos de un contexto del objeto son instancias de tipos de entidad que representan los datos en el origen de datos. Puede modificar, crear y eliminar los objetos en un contexto del objeto y Servicios de objeto realiza el seguimiento de los cambios realizados en estos objetos. Cuando se llama al método SaveChanges, Servicios de objeto genera y ejecuta comandos que llevan a cabo instrucciones equivalentes de inserción, actualización o eliminación con el origen de datos. Para obtener más información, vea Guardar los cambios y administrar la simultaneidad (Entity Framework).

Por ejemplo, suponga que ejecuta una consulta que devuelve un objeto SalesOrderHeader y una colección de objetos SalesOrderDetail relacionados. Podría enumerar mediante la colección y realizar las operaciones siguientes:

  • Cambiar la propiedad ShipDate de un pedido.

  • Elimine un elemento específico llamando al método DeleteObject.

  • Agregar un artículo al pedido llamando al método Add.

  • Llamar al método SaveChanges en el contexto del objeto cuando desea guardar los cambios del objeto de nuevo en el origen de datos.

En el ejemplo siguiente, se muestran varios cambios en los objetos en un contexto del objeto:

Dim order As SalesOrderHeader = _
context.SalesOrderHeader.Where( _
        "it.SalesOrderID = @id", New ObjectParameter( _
         "id", orderId)).First()

' Change the status and ship date of an existing order.
order.Status = 1
order.ShipDate = DateAndTime.Today

' Load items for the order, if not already loaded.
If Not order.SalesOrderDetail.IsLoaded Then
    order.SalesOrderDetail.Load()
End If

' Delete the first item in the order.
context.DeleteObject(order.SalesOrderDetail.First())

' Create a new item using the static Create method
' and add it to the order.
order.SalesOrderDetail.Add( _
    SalesOrderDetail.CreateSalesOrderDetail( _
    1, 0, 2, 750, 1, CDec(2171.2942), 0, 0, Guid.NewGuid(), _
    DateAndTime.Today))

' Save changes in the object context to the database.
Dim changes As Integer = context.SaveChanges()
SalesOrderHeader order =
    context.SalesOrderHeader.Where
    ("it.SalesOrderID = @id", new ObjectParameter(
     "id", orderId)).First();

// Change the status and ship date of an existing order.
order.Status = 1;
order.ShipDate = DateTime.Today;

// Load items for the order, if not already loaded.
if (!order.SalesOrderDetail.IsLoaded)
{
    order.SalesOrderDetail.Load();
}

// Delete the first item in the order.
context.DeleteObject(order.SalesOrderDetail.First());

// Create a new item using the static Create method 
// and add it to the order.
order.SalesOrderDetail.Add(
    SalesOrderDetail.CreateSalesOrderDetail(0,
    0, 2, 750, 1, (decimal)2171.2942, 0, 0,
    Guid.NewGuid(), DateTime.Today));

// Save changes in the object context to the database.
int changes = context.SaveChanges();

Agregar objetos

Si desea insertar datos en el origen de datos, debe crear una instancia de un tipo de entidad y agregar el objeto a un contexto del objeto. Para poder agregar un objeto nuevo, primero debe establecer todas las propiedades que no admitan los valores null. Considere usar el método estático Create nombreDeObjeto del tipo de entidad para crear una instancia nueva de un tipo de entidad. Las herramientas de Entity Data Model incluyen este método en cada clase cuando generan los tipos de entidad. Este método de creación se usa para crear una instancia de un objeto y establecer las propiedades de la clase que no pueden ser null. El método incluye un parámetro para cada propiedad que tenga aplicado el atributo Nullable="false" en el archivo de CSDL.

En el ejemplo siguiente se utiliza el método CreateSalesOrderHeader estático para crear una instancia nueva de la clase SalesOrderHeader.

' Create a new SalesOrderHeader using the static 
' CreateSalesOrderHeader method.
Dim order As SalesOrderHeader = _
    SalesOrderHeader.CreateSalesOrderHeader( _
    1, Convert.ToByte(1), DateTime.Now, DateTime.Today.AddMonths(2), _
    Convert.ToByte(1), False, String.Empty, customer.ContactID, shipMethod, _
    0, 0, 0, 0, Guid.NewGuid(), DateTime.Now)
// Create a new SalesOrderHeader using the static 
// CreateSalesOrderHeader method.
SalesOrderHeader order = SalesOrderHeader.CreateSalesOrderHeader(0,
    Convert.ToByte(1), DateTime.Now, DateTime.Today.AddMonths(2),
    Convert.ToByte(1), false, string.Empty, customer.ContactID, shipMethod, 
    0, 0, 0, 0, Guid.NewGuid(), DateTime.Now);

Para obtener más información, vea Cómo crear un objeto con el método de creación estático (Entity Framework).

Puede agregar objetos nuevos a un contexto del objeto llamando al método AddObject o a uno de los métodos AddTonombreDeConjuntoDeEntidades en el ObjectContext con tipo. También puede agregar un objeto a un contexto del objeto agregándolo a una EntityCollection existente. Al llamar al método Add en EntityCollection que está asociado a un contexto del objeto, el objeto que está agregando se agrega al mismo ObjectContext. De forma similar, puede agregar un objeto estableciendo la nueva instancia de objeto en Value de EntityReference.

Las propiedades de navegación definen las relaciones entre los objetos. Recomendamos que establezca estas propiedades cuando el objeto esté relacionado con otros objetos en el contexto del objeto. Por ejemplo, establezca la propiedad de la relación SalesOrderHeader de un nuevo objeto SalesOrderDetail en la instancia del pedido al que pertenece el elemento de línea. Al crear un nuevo objeto relacionado con otro objeto del contexto del objeto, agregue el objeto con uno de los métodos siguientes:

  • En una relación de uno a varios o de varios a varios, llame al método Add en EntityCollection y especifique el objeto relacionado.

  • En una relación de uno a uno o de varios a uno, establezca la propiedad Value del EntityReference en el objeto relacionado.

  • Llame al método AddObject para agregar el nuevo objeto al contexto del objeto y, a continuación, defina la relación utilizando uno de dos métodos los anteriores.

Al agregar objetos nuevos deben tenerse en cuenta las consideraciones siguientes:

  • Antes de llamar a SaveChanges, Servicios de objeto genera un valor de clave temporal para cada nuevo objeto que se agrega con el método AddObject. Una vez que se ha llamado a SaveChanges, el valor de identidad que el origen de datos asigna reemplaza el valor de clave cuando se inserta una nueva fila.

  • Si el origen de datos no genera el valor de clave de una entidad, tendrá que asignar un valor único. Si dos objetos tienen el mismo valor de clave especificado por el usuario, se produce una InvalidOperationException cuando se llama a SaveChanges. Si esto se produce, tendrá que asignar valores únicos y reintentar la operación.

  • Entity Framework establece automáticamente los valores de clave externa en el origen de datos al definir una relación entre los objetos y llamar a SaveChanges. Sin embargo, cuando una entidad se asigna a los procedimientos almacenados que realizan las inserciones, actualizaciones y eliminaciones, los valores de clave externa no se establecen automáticamente. En este caso, debe establecer los valores correctos a las propiedades que correspondan a la clave externa para el objeto relacionado. Para obtener más información, vea Compatibilidad con los procedimientos almacenados (Entity Framework).

Modificar objetos

Al cambiar una propiedad de navegación, escalar o compleja de un objeto, y llamar a SaveChanges, las actualizaciones se envían al origen de datos. Las relaciones entre los objetos se cambian al cambiar las propiedades de navegación, por ejemplo al cambiar el valor de EntityReference o quitar un objeto de EntityCollection. Para obtener más información, vea Cómo cambiar las relaciones entre objetos (Entity Framework).

Servicios de objeto realiza el seguimiento de los cambios en los objetos que están asociados a ObjectContext utilizando una instancia de IEntityChangeTracker. Hay una instancia de IEntityChangeTracker para cada objeto sometido a seguimiento. Las consultas devuelven los objetos en un estado Unchanged, a menos que la consulta use un elemento MergeOption establecido en NoTracking. Las herramientas de Entity Data Model generan las llamadas a los métodos de seguimiento de cambios en el establecedor de cada propiedad de un tipo de entidad, como en el ejemplo siguiente del establecedor de la propiedad Status en la clase SalesOrderHeader.

Set(ByVal value As Byte)
    Me.OnStatusChanging(value)
    Me.ReportPropertyChanging("Status")
    Me._Status = Global.System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value)
    Me.ReportPropertyChanged("Status")
    Me.OnStatusChanged()
End Set
set
{
    this.OnStatusChanging(value);
    this.ReportPropertyChanging("Status");
    this._Status = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
    this.ReportPropertyChanged("Status");
    this.OnStatusChanged();
}

El método ReportPropertyChanging y el método ReportPropertyChanged notifican los cambios de propiedad al IEntityChangeTracker. Si está utilizando clases de datos personalizadas con un Entity Data Model (EDM), también debería notificar los cambios de propiedad para habilitar el seguimiento a través de Servicios de objeto. Para obtener más información, vea Notificar los cambios en clases de datos personalizadas (Entity Framework).

El estado de un objeto se cambia de Unchanged a Modified cada vez que se llama a un establecedor de propiedad. Esto ocurre incluso cuando el valor que se establece es igual que el valor actual. Una vez llamado al método AcceptAllChanges, el estado vuelve a Unchanged. De forma predeterminada, se llama a AcceptAllChanges durante la operación SaveChanges.

Las herramientas de Entity Data Model también generan un par de métodos parciales denominados OnPropiedadChanging y OnPropiedadChanged. Se llama a estos métodos en el establecedor de propiedad. Extienda estos métodos en clases parciales para insertar una lógica de negocios personalizada durante los cambios de propiedad. Para obtener más información, vea Cómo ejecutar la lógica de negocios durante los cambios de propiedades (Entity Framework).

Al modificar objetos deben tenerse en cuenta las consideraciones siguientes:

  • Cuando se cambia cualquier propiedad escalar o compleja de un objeto complejo, el estado del objeto de entidad de nivel superior se cambia a Modified.

  • No se realiza el seguimiento de los cambios cuando los objetos están en el estado Detached. Los objetos están en este estado cuando los devuelve una consulta que utiliza la opción de mezcla NoTracking o después de desasociarse de ObjectContext al llamar a Detach.

  • Puede cambiar una relación entre dos objetos asignando el valor EntityReference a un nuevo objeto. En este caso, el Entity Framework actualiza automáticamente los valores de clave externa en el origen de datos al llamar a SaveChanges. Sin embargo, cuando una entidad se asigna a los procedimientos almacenados que realizan las inserciones, actualizaciones y eliminaciones, los valores de clave externa no se actualizan automáticamente. En este caso, debe establecer los valores correctos para el objeto relacionado a las propiedades que correspondan a la nueva relación. Para obtener más información, vea Compatibilidad con los procedimientos almacenados (Entity Framework).

Eliminar objetos

Al llamar al método DeleteObject en ObjectContext, se marca el objeto especificado para la eliminación. La fila no se elimina del origen de datos hasta que se llama a SaveChanges.

Al eliminar objetos deben tenerse en cuenta las consideraciones siguientes:

  • Cuando se elimina un objeto, también se elimina cualquier relación con otros objetos.

  • Cuando dos objetos tienen una relación restringida, al eliminar el objeto primario también se eliminan todos los objetos secundarios. Este resultado es el mismo que el de habilitar la propiedad CascadeDelete en la asociación para la relación. Para obtener más información, vea Restricciones referenciales (Entity Framework).

  • Cuando un objeto que devuelve una consulta está relacionado con uno o varios objetos diferentes, la consulta siempre devuelve información sobre esos objetos relacionados para que resulte más fácil eliminarlos. En algunos casos, esta información existente puede hacer que un UpdateException se produzca al intentar eliminar un objeto. Por ejemplo, recibirá esta excepción cuando la asociación que define la relación tenga el elemento <OnDelete Action="Cascade" /> especificado en el extremo primario de la asociación. Cuando ocurre esto, cargue explícitamente el objeto relacionado antes de llamar al método DeleteObject.

  • Puede llamar de nuevo al método DeleteObject para un objeto que ya se ha eliminado.

Para obtener más información, vea Cómo agregar, modificar y eliminar objetos (Entity Framework).

Crear objetos en un EntitySet concreto

Pueden darse casos en los que un tipo de entidad pertenece a varios conjuntos de entidades. Por ejemplo, en el caso en el que una base de datos tiene dos tablas con esquemas idénticos. Éste puede ser el caso si desea dividir los datos para generar un proceso de copia de seguridad más eficaz. Por ejemplo, podría tener los datos del cliente divididos entre las tablas Customer y CustomerArchive, donde CustomerArchive tiene el mismo esquema que Customer pero se utiliza para los clientes que no han realizado pedidos en más de seis meses. Se puede realizar una copia de seguridad nocturna de Customer, mientras que sólo puede realizarse una copia de CustomerArchive semanal. De una perspectiva de asignación, Customer y CustomerArchive deben pertenecer a diferentes conjuntos de entidades. El Entity Framework admite este escenario permitiendo a un tipo de entidad existir en uno o más conjuntos de entidades. Para obtener más información, vea Conjuntos de entidades (EDM).

Cuando un tipo de entidad existe en varios conjuntos de entidades, los servicios de objeto le permiten agregar nuevas instancias del tipo a un conjunto específico de entidades. Para ello, debe especificar el valor de entitySetName al llamar al método AddObject para agregar el objeto al contexto del objeto. Para obtener más información, vea Cómo agregar un objeto a un conjunto de entidades específico (Entity Framework).

Las herramientas de Entity Data Model también generan métodos AddTonombreDeConjuntoDeEntidades en ObjectContext, con un método para cada conjunto de entidades que se define en el modelo conceptual. Estos métodos llaman a AddObject y pasan el valor EntitySetName del método concreto. Utilice estos métodos para agregar objetos en conjuntos de entidades concretos.

Vea también

Tareas

Cómo definir un modelo con múltiples conjuntos de entidades por tipo (Entity Framework)