Werken met entiteitsstatussen

In dit onderwerp wordt beschreven hoe u entiteiten toevoegt aan en koppelt aan een context en hoe Entity Framework deze verwerkt tijdens SaveChanges. Entity Framework zorgt ervoor dat de status van entiteiten wordt bijgehouden terwijl ze zijn verbonden met een context, maar in ontkoppelde of N-tier-scenario's kunt u EF laten weten in welke status uw entiteiten moeten verkeren. De technieken die in dit onderwerp worden weergegeven, zijn evenzeer van toepassing op modellen die zijn gemaakt met Code First en de EF Designer.

Entiteitsstatussen en SaveChanges

Een entiteit kan zich in een van de vijf statussen bevinden, zoals gedefinieerd door de EntityState-opsomming. Deze staten zijn:

  • Toegevoegd: de entiteit wordt bijgehouden door de context, maar bestaat nog niet in de database
  • Ongewijzigd: de entiteit wordt bijgehouden door de context en bestaat in de database en de eigenschapswaarden zijn niet gewijzigd van de waarden in de database
  • Gewijzigd: de entiteit wordt bijgehouden door de context en bestaat in de database en sommige of alle eigenschapswaarden zijn gewijzigd
  • Verwijderd: de entiteit wordt bijgehouden door de context en bestaat in de database, maar is gemarkeerd voor verwijdering uit de database wanneer SaveChanges de volgende keer wordt aangeroepen
  • Losgekoppeld: de entiteit wordt niet bijgehouden door de context

SaveChanges doet verschillende dingen voor entiteiten in verschillende statussen:

  • Ongewijzigde entiteiten worden niet aangeraakt door SaveChanges. Updates worden niet verzonden naar de database voor entiteiten met de status Ongewijzigd.
  • Toegevoegde entiteiten worden ingevoegd in de database en worden vervolgens ongewijzigd wanneer SaveChanges retourneert.
  • Gewijzigde entiteiten worden bijgewerkt in de database en worden vervolgens ongewijzigd wanneer SaveChanges retourneert.
  • Verwijderde entiteiten worden verwijderd uit de database en worden vervolgens losgekoppeld van de context.

In de volgende voorbeelden ziet u manieren waarop de status van een entiteit of entiteitsgrafiek kan worden gewijzigd.

Een nieuwe entiteit toevoegen aan de context

Er kan een nieuwe entiteit aan de context worden toegevoegd door de methode Toevoegen op DbSet aan te roepen. Hiermee wordt de entiteit in de status Toegevoegd geplaatst, wat betekent dat deze wordt ingevoegd in de database wanneer SaveChanges de volgende keer wordt aangeroepen. Voorbeeld:

using (var context = new BloggingContext())
{
    var blog = new Blog { Name = "ADO.NET Blog" };
    context.Blogs.Add(blog);
    context.SaveChanges();
}

Een andere manier om een nieuwe entiteit aan de context toe te voegen, is door de status te wijzigen in Toegevoegd. Voorbeeld:

using (var context = new BloggingContext())
{
    var blog = new Blog { Name = "ADO.NET Blog" };
    context.Entry(blog).State = EntityState.Added;
    context.SaveChanges();
}

Ten slotte kunt u een nieuwe entiteit toevoegen aan de context door deze te koppelen aan een andere entiteit die al wordt bijgehouden. Dit kan zijn door de nieuwe entiteit toe te voegen aan de eigenschap verzamelingsnavigatie van een andere entiteit of door een verwijzingsnavigatie-eigenschap van een andere entiteit in te stellen om naar de nieuwe entiteit te verwijzen. Voorbeeld:

using (var context = new BloggingContext())
{
    // Add a new User by setting a reference from a tracked Blog
    var blog = context.Blogs.Find(1);
    blog.Owner = new User { UserName = "johndoe1987" };

    // Add a new Post by adding to the collection of a tracked Blog
    blog.Posts.Add(new Post { Name = "How to Add Entities" });

    context.SaveChanges();
}

Houd er rekening mee dat voor al deze voorbeelden als de entiteit die wordt toegevoegd verwijzingen bevat naar andere entiteiten die nog niet worden bijgehouden, deze nieuwe entiteiten ook worden toegevoegd aan de context en worden ingevoegd in de database wanneer SaveChanges de volgende keer wordt aangeroepen.

Een bestaande entiteit koppelen aan de context

Als u een entiteit hebt die u al kent in de database, maar die momenteel niet wordt bijgehouden door de context, kunt u de context vertellen om de entiteit bij te houden met behulp van de attach-methode op DbSet. De entiteit heeft de status Ongewijzigd in de context. Voorbeeld:

var existingBlog = new Blog { BlogId = 1, Name = "ADO.NET Blog" };

using (var context = new BloggingContext())
{
    context.Blogs.Attach(existingBlog);

    // Do some more work...  

    context.SaveChanges();
}

Houd er rekening mee dat er geen wijzigingen in de database worden aangebracht als SaveChanges wordt aangeroepen zonder dat de gekoppelde entiteit wordt gemanipuleerd. Dit komt doordat de entiteit de status Ongewijzigd heeft.

Een andere manier om een bestaande entiteit aan de context te koppelen, is door de status te wijzigen in Ongewijzigd. Voorbeeld:

var existingBlog = new Blog { BlogId = 1, Name = "ADO.NET Blog" };

using (var context = new BloggingContext())
{
    context.Entry(existingBlog).State = EntityState.Unchanged;

    // Do some more work...  

    context.SaveChanges();
}

Houd er rekening mee dat voor beide voorbeelden als de entiteit die wordt gekoppeld verwijzingen heeft naar andere entiteiten die nog niet zijn bijgehouden, worden deze nieuwe entiteiten ook gekoppeld aan de context met de status Ongewijzigd.

Een bestaande maar gewijzigde entiteit koppelen aan de context

Als u een entiteit hebt waarvan u weet dat deze al bestaat in de database, maar waaraan mogelijk wijzigingen zijn aangebracht, kunt u de context vertellen om de entiteit te koppelen en de status ervan in te stellen op Gewijzigd. Voorbeeld:

var existingBlog = new Blog { BlogId = 1, Name = "ADO.NET Blog" };

using (var context = new BloggingContext())
{
    context.Entry(existingBlog).State = EntityState.Modified;

    // Do some more work...  

    context.SaveChanges();
}

Wanneer u de status wijzigt in Gewijzigd worden alle eigenschappen van de entiteit gemarkeerd als gewijzigd en worden alle eigenschapswaarden naar de database verzonden wanneer SaveChanges wordt aangeroepen.

Als de entiteit die wordt gekoppeld verwijzingen bevat naar andere entiteiten die nog niet worden bijgehouden, worden deze nieuwe entiteiten gekoppeld aan de context in de status Ongewijzigd. Deze worden niet automatisch gewijzigd. Als u meerdere entiteiten hebt die moeten worden gemarkeerd als Gewijzigd, moet u de status voor elk van deze entiteiten afzonderlijk instellen.

De status van een bijgehouden entiteit wijzigen

U kunt de status wijzigen van een entiteit die al wordt bijgehouden door de eigenschap State in te stellen voor de vermelding. Voorbeeld:

var existingBlog = new Blog { BlogId = 1, Name = "ADO.NET Blog" };

using (var context = new BloggingContext())
{
    context.Blogs.Attach(existingBlog);
    context.Entry(existingBlog).State = EntityState.Unchanged;

    // Do some more work...  

    context.SaveChanges();
}

Houd er rekening mee dat het aanroepen van Toevoegen of Koppelen voor een entiteit die al is bijgehouden, ook kan worden gebruikt om de entiteitsstatus te wijzigen. Als u bijvoorbeeld Attach aanroept voor een entiteit die zich momenteel in de status Toegevoegd bevindt, wordt de status gewijzigd in Ongewijzigd.

Patroon invoegen of bijwerken

Een veelvoorkomend patroon voor sommige toepassingen is het toevoegen van een entiteit als nieuw (wat resulteert in een database invoegen) of een entiteit als bestaande koppelen en markeren als gewijzigd (wat resulteert in een database-update) afhankelijk van de waarde van de primaire sleutel. Wanneer u bijvoorbeeld primaire sleutels gebruikt die door de database zijn gegenereerd, is het gebruikelijk om een entiteit met een nulsleutel als nieuw te behandelen en een entiteit met een niet-nulsleutel als bestaande. Dit patroon kan worden bereikt door de entiteitsstatus in te stellen op basis van een controle van de primaire-sleutelwaarde. Voorbeeld:

public void InsertOrUpdate(Blog blog)
{
    using (var context = new BloggingContext())
    {
        context.Entry(blog).State = blog.BlogId == 0 ?
                                   EntityState.Added :
                                   EntityState.Modified;

        context.SaveChanges();
    }
}

Houd er rekening mee dat wanneer u de status wijzigt naar 'Gewijzigd', alle eigenschappen van de entiteit als gewijzigd worden gemarkeerd. Alle eigenschapswaarden worden naar de database verzonden wanneer SaveChanges wordt aangeroepen.