Procédure : modifier les relations entre les objets (Entity Framework)

Cette rubrique indique comment utiliser l'objet EntityReference pour modifier une relation entre deux objets dans le contexte de l'objet. Lorsque la méthode SaveChanges est appelée, la modification de la relation est rendue persistante dans la base de données comme une modification de la clé étrangère dans la table connexe. Cette rubrique montre également comment traiter l'événement AssociationChanged.

L'exemple de cette rubrique est basé sur le modèle de vente Adventure Works Sales Model. Pour exécuter le code de cet exemple, vous devez déjà avoir ajouté le modèle de vente AdventureWorks Sales Model à votre projet et configuré ce dernier pour qu'il utilise Entity Framework. Pour ce faire, exécutez les procédures décrites dans Procédure : configurer manuellement un projet Entity Framework et Procédure : définir manuellement un modèle EDM (Entity Data Model) (Entity Framework). Vous devez aussi ajouter l'instruction using suivante (Imports en Visual Basic) dans votre code :

Imports System.ComponentModel
using System.ComponentModel;

Exemple

Cet exemple indique comment utiliser l'objet EntityReference pour modifier une relation entre un objet SalesOrderHeader et un objet Address connexe qui représente l'adresse d'expédition pour la commande.

'Define the order and new address IDs.
Dim orderId As Integer = 43669
Dim newAddressId As Integer = 26

Using context As New AdventureWorksEntities()
    Try
        ' Get the billing address to change to.
        Dim newAddress As Address = context.Address _
            .Where("it.AddressID = @addressId", _
            New ObjectParameter("addressId", newAddressId)) _
        .First()

        ' Get the order being changed.
        Dim order As SalesOrderHeader = context.SalesOrderHeader _
            .Where("it.SalesOrderID = @orderId", _
            New ObjectParameter("orderId", orderId)).First()

        ' Load the current billing address.
        If Not order.Address1Reference.IsLoaded Then
            order.Address1Reference.Load()
        End If

        ' Write the current billing street address.
        Console.WriteLine("Current street: " _
            + order.Address1.AddressLine1)

        ' Change the billing address.
        If Not order.Address1.Equals(newAddress) Then
            order.Address1 = newAddress

            ' Write the changed billing street address.
            Console.WriteLine("Changed street: " _
                + order.Address1.AddressLine1)
        End If

        ' If the address change succeeds, save the changes.
        context.SaveChanges()

        ' Write the current billing street address.
        Console.WriteLine("Current street: " _
            + order.Address1.AddressLine1)
    Catch ex As ApplicationException
        ' Handle the exception raised in the ShippingAddress_Changed 
        ' handler when the status of the order prevents the 
        ' shipping address from being changed. Don't retry because
        ' the relationship is in an inconsistent state and calling 
        ' SaveChanges() will result in an UpdateException.
        Console.WriteLine(ex.ToString())
    Catch ex As InvalidOperationException
        Console.WriteLine(ex.ToString())
    End Try
End Using
// Define the order and new address IDs.
int orderId = 43669;
int newAddressId = 26;

using (AdventureWorksEntities context 
    = new AdventureWorksEntities())
{
    try
    {
        // Get the billing address to change to.
        Address newAddress = context.Address
            .Where("it.AddressID = @addressId",
            new ObjectParameter("addressId", newAddressId))
            .First();

        // Get the order being changed.
        SalesOrderHeader order = context.SalesOrderHeader
            .Where("it.SalesOrderID = @orderId",
            new ObjectParameter("orderId", orderId)).First();

        // Load the current billing address.
        if (!order.Address1Reference.IsLoaded)
        {
            order.Address1Reference.Load();
        }

        // Write the current billing street address.
        Console.WriteLine("Current street: " 
            + order.Address1.AddressLine1);

        // Change the billing address.
        if (!order.Address1.Equals(newAddress))
        {
            order.Address1 = newAddress;

            // Write the changed billing street address.
            Console.WriteLine("Changed street: "
                + order.Address1.AddressLine1);
        }

        // If the address change succeeds, save the changes.
        context.SaveChanges();

        // Write the current billing street address.
        Console.WriteLine("Current street: "
            + order.Address1.AddressLine1);
    }
    catch (ApplicationException ex)
    {
        // Handle the exception raised in the ShippingAddress_Changed 
        // handler when the status of the order prevents the 
        // shipping address from being changed. Don't retry because
        // the relationship is in an inconsistent state and calling 
        // SaveChanges() will result in an UpdateException.
        Console.WriteLine(ex.ToString());
    }
    catch (InvalidOperationException ex)
    {
        Console.WriteLine(ex.ToString());
    }
}

Cet exemple étend l'exemple précédent et indique comment vérifier l'état de la commande lorsque l'adresse d'expédition est modifiée en gérant l'événement AssociationChanged sur le EntityReference pour l'objet Address qui représente l'adresse d'expédition. Si l'état de la commande est supérieur à 3, la commande ne peut pas être modifiée et une exception est déclenchée. Le délégué est défini dans le constructeur pour la classe partielle SalesOrderHeader et le gestionnaire de cet événement est également implémenté dans cette classe partielle. Cela garantit que l'état de la commande est vérifié toutes les fois que l'adresse d'expédition d'une commande est modifiée.

Pour valider des modifications à l'autre extrémité de la relation SalesOrderHeader-Address, une technique semblable pourrait être utilisée pour enregistrer l'événement AssociationChanged sur le EntityCollection des objets SalesOrderHeader associés à une adresse d'expédition.

Partial Public Class SalesOrderHeader
    ' SalesOrderHeader default constructor.
    Public Sub New()
        ' Register the handler for changes to the 
        ' shipping address (Address1) reference.
        AddHandler Me.Address1Reference.AssociationChanged, _
        AddressOf ShippingAddress_Changed
    End Sub

    ' AssociationChanged handler for the relationship 
    ' between the order and the shipping address.
    Private Sub ShippingAddress_Changed(ByVal sender As Object, _
        ByVal e As CollectionChangeEventArgs)
        ' Check for a related reference being removed. 
        If e.Action = CollectionChangeAction.Remove Then
            ' Check the order status and raise an exception if 
            ' the order can no longer be changed.
            If Me.Status > 3 Then
                Throw New ApplicationException( _
                    "The shipping address cannot " _
                + "be changed because the order has either " _
                + "already been shipped or has been cancelled.")
            End If
        End If
    End Sub
End Class
public partial class SalesOrderHeader
{
    // SalesOrderHeader default constructor.
    public SalesOrderHeader()
    {
        // Register the handler for changes to the 
        // shipping address (Address1) reference.
        this.Address1Reference.AssociationChanged
            += new CollectionChangeEventHandler(ShippingAddress_Changed);
    }

    // AssociationChanged handler for the relationship 
    // between the order and the shipping address.
    private void ShippingAddress_Changed(object sender,
        CollectionChangeEventArgs e)
    {
        // Check for a related reference being removed. 
        if (e.Action == CollectionChangeAction.Remove)
        {
            // Check the order status and raise an exception if 
            // the order can no longer be changed.
            if (this.Status > 3)
            {
                throw new ApplicationException(
                    "The shipping address cannot "
                + "be changed because the order has either "
                + "already been shipped or has been cancelled.");
            }
        }
    }
}

Voir aussi

Autres ressources

Utilisation d'objets (Tâches Entity Framework)