Entity Framework .Remove() versus .DeleteObject()

Je kunt een item uit een database verwijderen met EF door de volgende twee methoden te gebruiken.

De eerste staat op de EntityCollectionen de tweede op de ObjectContext.

Wanneer moet elk worden gebruikt?

Heeft de ene de voorkeur boven de andere?

Remove()retourneert een boolen DeleteObject()retourneert void.


Antwoord 1, autoriteit 100%

Het is over het algemeen niet correct dat u met beide methoden “een item uit een database kunt verwijderen“. Om precies te zijn is het zo:

  • ObjectContext.DeleteObject(entity)markeert de entiteit als Deletedin de context. (Het is EntityStateis daarna Deleted.) Als je daarna SaveChangesaanroept, stuurt EF een SQL-statement DELETEnaar de databank. Als er geen referentiële beperkingen in de database worden geschonden, wordt de entiteit verwijderd, anders wordt er een uitzondering gegenereerd.

  • EntityCollection.Remove(childEntity)markeert de relatie tussen ouder en childEntityals Deleted. Als de childEntityzelf uit de database wordt verwijderd en wat er precies gebeurt als je SaveChangesaanroept, hangt af van het soort relatie tussen de twee:

    • Als de relatie optioneelis, dwz dat de externe sleutel die van het kind naar de ouder in de database verwijst, NULL-waarden toestaat, wordt deze buitenlandse sleutel ingesteld naar null en als u SaveChangesaanroept, wordt deze NULL-waarde voor de childEntitynaar de database geschreven (dwz de relatie tussen de twee wordt verwijderd) . Dit gebeurt met een SQL UPDATE-instructie. Er vindt geen DELETE-instructie plaats.

    • Als de relatie vereistis (de FK staat geen NULL-waarden toe) en de relatie is niet identificerend(wat betekent dat de refererende sleutel geen deel uitmaakt van de (samengestelde) primaire sleutel van het kind) u moet het kind toevoegen aan een andere ouder of u moet het kind expliciet verwijderen (met DeleteObjectdan). Als je dit niet doet, wordt een referentiële beperking geschonden en EF zal een uitzondering genereren wanneer je SaveChangesaanroept – de beruchte De relatie kan niet worden gewijzigd omdat een of meer van de buitenlandse- sleuteleigenschappen is niet-nullableuitzondering of vergelijkbaar.

    • Als de relatie identificerendis (het is noodzakelijkerwijs vereist, omdat geen enkel deel van de primaire sleutel NULLkan zijn) zal EF markeer de childEntityook als Deleted. Als u SaveChangesaanroept, wordt een SQL DELETE-instructie naar de database verzonden. Als er geen andere referentiële beperkingen in de database worden geschonden, wordt de entiteit verwijderd, anders wordt er een uitzondering gegenereerd.

Ik ben eigenlijk een beetje in de war over het gedeelte Opmerkingen op de MSDN-paginaje hebt gelinkt omdat er staat: “Als de relatie een referentiële integriteitsbeperking heeft, markeert het aanroepen van de Remove-methode op een afhankelijk object zowel de relatie als het afhankelijke object voor verwijdering.“. Dit lijkt mij onnauwkeurig of zelfs verkeerd omdat alle drie bovenstaande gevallen een “referentiële integriteitsbeperking” hebben, maar alleen in het laatste geval wordt het kind daadwerkelijk verwijderd. (Tenzij ze met “afhankelijk object” een object bedoelen dat deelneemt aan een identificerende relatie, wat echter een ongebruikelijke terminologie zou zijn.)


Antwoord 2, autoriteit 5%

Als je Deleted echt wilt gebruiken, moet je je externe sleutels nullable maken, maar dan krijg je verweesde records (wat een van de belangrijkste redenen is waarom je dat in eerste instantie niet zou moeten doen plaats). Gebruik dus gewoon Remove()

ObjectContext.DeleteObject(entity)markeert de entiteit als Verwijderd in de context. (Daarna wordt EntityState verwijderd.) Als je daarna SaveChanges aanroept, stuurt EF een SQL DELETE-statement naar de database. Als er geen referentiële beperkingen in de database worden geschonden, wordt de entiteit verwijderd, anders wordt er een uitzondering gegenereerd.

EntityCollection.Remove(childEntity)markeert de relatie tussen ouder en childEntity als verwijderd. Als de childEntity zelf uit de database wordt verwijderd en wat er precies gebeurt als u SaveChanges aanroept, hangt af van het soort relatie tussen de twee:

Het vermelden waard is dat het instellen van .State = EntityState.Deletedtriggert niet automatisch gedetecteerde wijziging.(archief)

Other episodes