tags:

views:

634

answers:

1

I am writing a class that will (hopefully) allow manipulation of data through a LINQ to SQL layer without having to know what individual objects you are working with. So far, it works fine for cascading selects and inserts, but I am having a hard time with updates.

Here is the save method I am using:

if ((long)entity.GetType().GetProperty(GetPrimaryKeyName(entity)).GetValue(entity, null) == 0)
            {
                Context.GetTable(entity.GetType()).InsertOnSubmit(entity);
            }
            else
            {
                Context.GetTable(entity.GetType()).Attach(entity, true);
            }

            foreach (PropertyInfo property in entity.GetType().GetProperties())
            {
                if (property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDefinition() == typeof(EntitySet<>))
                {
                    IEnumerable children = (IEnumerable)property.GetValue(entity, null);
                    foreach (object child in children)
                    {
                        Save(child);
                    }
                }
            }

This works until I have a child object as part of an update. For example, if I pass in a Customer object with an Address child object that needs to be updated and not inserted, as soon as I Attach the Customer object I now have TWO Address objects in my EntitySet - the one pulled up from the database, and the new one. I then get an exception "Cannot attach an entity that already exists" when it attempts to attach the first Address child object.

Any ideas?

+1  A: 

Could you possibly attach the child entities before you attach the parent entity? Would that prevent the attach issue?

Just use reflection to get all of the EntityRef objects, and attach the Entity property of each to the appropriate table.

toast
I ended up doing just that, and you are correct. Attaching from the "bottom up" solved the problem.
Brian