views:

136

answers:

2

Hi,
I'm trying to set up what I think is a pretty simple data model in the Entity Framework. I've got two entities, OrderHeader and OrderLine.

OrderHeader

+---------+--------+
| Name    | Type   |
+---------+--------+
| Id      |  Int   |
| Name    | String |
+---------+--------+

OrderLine

+---------+--------+
| Name    | Type   |
+---------+--------+
| Id      |  Int   |
| OrderId |  Int   |
| Name    | String |
+---------+--------+

Whenever I call OrderHeader.OrderLines.Remove(someOrderLine), I want the OrderLine to be deleted from the database instead of leaving it orphaned, but I can't seem to do this in the Entity Framework. The Documentation states I should use a Referential Constraint, but that feature doesn't appear to work (For example, http://msdn.microsoft.com/en-us/library/dd456813%28VS.100%29.aspx refers to menus that don't exist). Any Ideas?

A: 

When you call OrderHeader.OrderLines.Remove(someOrderLine) your removing the relationship (ie the foriegn key) if you want to just get rid of the order line do something like:

   context.DeleteObject(someOrderLine);
   context.SaveChanges();
DeletedAccount
That only works if I want to delete the OrderLines when I delete the OrderHeader. I want to delete the OrderLine when I remove it from the OrderHeader's collection of OrderLines
LPCRoy
sorry, misunderstood, I'll edit
DeletedAccount
A: 

Someone helped me write the following helper function to deal with this situation. First we define this helper function inside of the ObjectContext

private void DeleteOrphans<TEntity, TRelatedEntity>(Func<TEntity, EntityCollection<TRelatedEntity>> collectionAccessor)
        where TEntity : EntityObject
        where TRelatedEntity : EntityObject
    {
        ObjectStateManager.ObjectStateManagerChanged += (_, e) =>
        {
            if (e.Action == System.ComponentModel.CollectionChangeAction.Add)
            {
                var entity = e.Element as TEntity;
                if (entity != null)
                {
                    var collection = collectionAccessor(entity) as System.Data.Objects.DataClasses.EntityCollection<TRelatedEntity>;
                    if (collection != null)
                    {
                        collection.AssociationChanged += (__, e2) =>
                        {
                            if ((e2.Action == System.ComponentModel.CollectionChangeAction.Remove))
                            {
                                var relatedEntity = e2.Element as TRelatedEntity;
                                if (relatedEntity != null)
                                {
                                    DeleteObject(relatedEntity);
                                }
                            }
                        };
                    }
                }
            }
        };
    }

And then in the constructor for the context, we call something similar to:

DeleteOrphans<OrderHeader, OrderLine>(x => x.OrderLines);
LPCRoy