Entity Framework Feature Suggestions

Delete orphans support

Entity Framework should support automatic deletion of orphan records, the way "all-delete-orphan" works in NHibernate.

If I have a one-to-many relationship between Orders and OrderLines, and code inside the Order class calls OrderLines.Remove(orderLine), this should cause the order line to be deleted when I save changes. Currently, EF attempts to set the order line's OrderID to NULL. If the OrderID column is non-nullable, the update fails with a constraint violation error.

I found this forum post in which Daniel Simmons from Microsoft says EF doesn't support this: http://social.msdn.microsoft.com/forums/en-us/adodotnetentityframework/thread/CB9C1C4A-DF12-44E4-B00A-417C80BF5453

This is an important feature for an ORM, since it's difficult to cleanly work around it. One workaround is to add a call to context.OrderLines.Delete(orderLine) immediately when an order line is removed in memory. But the Order aggregate should be able to manage its order lines without taking a direct dependency on the ORM.

444 votes
Vote
Sign in
Check!
(thinking…)
Reset
or sign in with
  • facebook
  • google
    Password icon
    I agree to the terms of service
    Signed in as (Sign out)
    You have left! (?) (thinking…)
    Richard BeierRichard Beier shared this idea  ·   ·  Flag idea as inappropriate…  ·  Admin →
    Diego VegaAdminDiego Vega (Development Lead, DataFx) responded  · 

    Reverting status from “under review” to “no status” since we aren’t currently working on this. We will still consider it for future releases.

    11 comments

    Sign in
    Check!
    (thinking…)
    Reset
    or sign in with
    • facebook
    • google
      Password icon
      I agree to the terms of service
      Signed in as (Sign out)
      Submitting...
      • Raffaele GarofaloRaffaele Garofalo commented  ·   ·  Flag as inappropriate

        This is absolutely a shame, we work with multiple ORMs like NHibernate and they simply handle the Remove children object by deleting the object from the Database. How is possible that we are working with version 6 of EF and we still have this basics ORM issues? Shouldn't be version 0.6?

      • Jordan MJordan M commented  ·   ·  Flag as inappropriate

        I have already commented on this once, so apologies for the spam - but every time I come back to this it seems worse.

        I know there is plenty of code around where people are accessing their DbContext directly in the service or UI layers of their applications where this wouldn't be so much of an issue.

        But.... if you have properly wrapped Entity Framework up in your data access layer this gets really annoying. It means you end up having to create a DAO for every entity that you might possibly need to delete. Normally I would only have DAOs for the main entities in my application, and manage their children via the collections hanging off them.

        Please fix this.

      • Jordan MJordan M commented  ·   ·  Flag as inappropriate

        This is a must have feature. I cannot believe that Entity Framework hasn't got this, This gives NHibernate a simple but significant advantage.

        This is an ORM - the O stands for "Object" and one of the *main* benefits of using an ORM is that as much as possible it should allow you to do object oriented programming. Automatically syncing trees of objects to the database is a massive part of that.

        If a collection of an entities makes up part of its parent, if one of those objects is removed from its parents collection then it should be deleted from the database. You shouldn't have to then go and delete it again using a call to your data access layer.

      • Anonymous commented  ·   ·  Flag as inappropriate

        I agree with Vir, I'll move on NHibernate just because of this. My project uses DDD and I don't want to inject IStuffRepositories in my domain objects just to remove something from the collection. To me the purpose of an ORM if actually to avoid to have to do this kind of things.

      • VirVir commented  ·   ·  Flag as inappropriate

        Lack of this functionality in Entity Framework makes that whole ORM just useless in real life cases where POCO objects should not be aware of persistence layer. Just simple property-level attribute like [DeleteOnRemove] would do the trick, better yet second method like .Delete for collection that will actualy delete object as oposite to current .Remove method which could be left unchanged.

      • Kieron DyeKieron Dye commented  ·   ·  Flag as inappropriate

        Unfortunately the identifying relationship is not always possible. From my understanding to make the identifying relationship work you have to make the foreign key part of the primary key. We have a scenario where the child has derived types. The derived type tables have the child key but do not have the parent key and so modifying the child to use the parent key in its own primary key breaks the inheritance. Presumably this would also be a problem if the child had children.

      • Graeme MillerGraeme Miller commented  ·   ·  Flag as inappropriate

        This can be handled by making the OrderLine key an identifying relationship http://msdn.microsoft.com/en-us/library/ee373856.aspx.

        If the orderline key is a composite and contains the parent key (OrderId) you can use remove on the collection and it works. However it is far from clear and it should be handled as an option.

        See here http://stackoverflow.com/questions/11033348/is-it-possible-to-remove-child-from-collection-and-resolve-issues-on-savechanges

      • Jin HuihuiJin Huihui commented  ·   ·  Flag as inappropriate

        I also think this is very important, Linq to Sql can do this, why can't EF do this. I strongly suggest this can be addressed by EF5

      • Richard BeierRichard Beier commented  ·   ·  Flag as inappropriate

        I was able to work around this by putting the following in my OrderRepository, before the call to context.SaveChanges():

        var orphans = _context.ObjectStateManager.GetObjectStateEntries(EntityState.Modified)
        .Select(x => x.Entity)
        .OfType<OrderLine>()
        .Where(x => x.OrderID == null)
        .ToList();

        foreach ( var orphan in orphans )
        _context.DeleteObject(orphan);

        But I still think there should be an option for this in the mapping :).

        Thanks,
        Richard

      Feedback and Knowledge Base