-6

Simplified, I have an Entity Framework mapping two tables to objects: Items and Properties. Each item has certain properties (one to many).

From outside my program, I receive "dead" items with properties, which are new items or updates of existing items, with their properties. This data could be from an WCF call, a web form POST, a deserialization: the point is I want to insert and update items and properties in the database with unlinked data I receive.

I found various related questions and answers (of which not all even compile). The problem is I have to write loads of code to synchronize the properties of an existing item and an incoming, updated item:

private static void UpdateProperties(Item existingItem, Item updatedItem, TestdatabaseEntities context)
{
    // Find deleted properties
    foreach (var existingProp in existingItem.Properties.ToList()) // ToList() to work on a local copy, otherwise you'll be removing items from an enumeration
    {
        var inUpdate = updatedItem.Properties.Where(p => p.Name == existingProp.Name).FirstOrDefault();

        if (inUpdate == null)
        {
            // Property with this Name was not found as property in the updated item, delete it
            context.Properties.DeleteObject(existingProp);
        }
    }

    // Find added or updated properties
    foreach (var updatedProp in updatedItem.Properties)
    {
        var inDatabase = existingItem.Properties.Where(p => p.ItemID == existingItem.ID && p.Name == updatedProp.Name).FirstOrDefault();

        if (inDatabase == null)
        {
            // Added
            inDatabase = new Property { Name = updatedProp.Name };
            existingItem.Properties.Add(inDatabase);
        }

        // Updated ( & added), map properties (could be done with something like AutoMapper)
        inDatabase.Value = updatedProp.Value;
        // etc...
    }

    context.SaveChanges();
}

You see, there are various references to specific properties of the objects (existingItem.Properties, p.Name == existingProp.Name, p.ItemID == existingItem.ID), but it will be doable to build a more generic version of this method, and maybe even fiddle in a little recursion (what if a Property itself has references to other entities?).

However, I was wondering: can this (whole process, or parts of it) be done more easily? And no, I cannot delete all Properties from an Item and re-add them upon an update, because there's other data in those entities I want to preserve.

Community
  • 1
  • 1
CodeCaster
  • 147,647
  • 23
  • 218
  • 272

1 Answers1

4

As a developer it is your job to write a code :) and this is not "a lot of code".

There is no global generic way to handle this code. You can probably find a way to generalize your sample but it will still be tailored just for particular set of cases. Your simple method contains a lot of code which is tightly coupled with Item and Property class. Generalizing this code would require injecting delegates or expressions handling these dependencies outside of your method.

Ladislav Mrnka
  • 360,892
  • 59
  • 660
  • 670
  • 7
    As a developer, it is my job to constantly think _"Can this be done in a better way?"_, hence my question. ;-) I was hoping there was a more generic way of doing this, preferably built into EF, because as I stated this is a simplified example and I don't want to keep repeating my code. – CodeCaster Mar 01 '12 at 10:36
  • 3
    No EF doesn't contain any built in mechanism to solve this - [here](http://stackoverflow.com/questions/3635071/update-relationships-when-saving-changes-of-ef4-poco-objects/3635326#3635326) is my analysis. – Ladislav Mrnka Mar 01 '12 at 10:48
  • 1
    I already found that great post, now I see I forgot to link to it in my question. Thanks anyway. – CodeCaster Mar 01 '12 at 10:53