Mar 23, 2010

The "OnDelete" property of navigation in Entity Framework

This property affects the the behavior of entity framework when delete an entity. Here are two scenario.

[Fact]
        public void can_delete_order_with_lines_loaded()
        {
            TestEntities db = new TestEntities();
            Order o1 = db.Orders.Include("OrderLines").First();
            db.DeleteObject(o1);
            db.SaveChanges();

        }

        [Fact]
        public void can_delete_order_with_no_lines_loaded()
        {
            TestEntities db = new TestEntities();
            Order o1 = db.Orders.First();
            db.DeleteObject(o1);
            db.SaveChanges();

        }

If the values of OnDelete is Cascade, in the first case, because ef knows there are orderlines of the order, because they are loaded in memory, so it will delete the children (orderlies) first, then delete the order. In the second case, because the ef think that order has no child, because there is no children in memory, so it will just delete the order.

If the values of OnDelete is "None", in the first case, it will throw exception like "System.InvalidOperationException : The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.". Because, ef knows that it has children in memory, it can not delete them unless you manually delete the children first. In the second case, because there is no children in memory, ef will just delete the order.

Please note that ef does not consider the foreign key property between tables in database, when it do the above operations. So if the above behavior is just delete the parent, but in database there is no such cascade for the foreign key, it will failed as well. But the values of navigation does affect the database generation script if you choose to generate database from the model. If it is cascade, it will generate a foreign key with cascade, if not it will generate a foreign key with no cascade. But this is design time behavior, but not runtime behavior