views:

92

answers:

2

I'm trying to update an entity using a stub. This works fine for changing records, unless I try to set the value back to the default value forr the column. Eg: If the default value is 0, I can change to and from any value except zero, but the changes aren't saved if I try to set it back to zero. This is the code I'm using:

var package = new Package() {
    PackageID = 4
};
...
public static void EditPackage(Package package) {
    using(var context = new ShopEntities()) {
        context.Packages.MergeOption = MergeOption.NoTracking;
        var existing = new Package() {
            PackageID = package.PackageID
        };
        context.AttachTo("Packages", existing);
        context.ApplyPropertyChanges("ShopEntities.Packages", package);
        context.AcceptAllChanges(); // doesn't make a difference
        System.Diagnostics.Debug.WriteLine((package.DateSent.HasValue ? package.DateSent.Value.ToString("D") : "none") + "\t\t" + package.IsReceived);
        context.SaveChanges();
    }
}

In the example above, DateSent's default value is null (It's a DateTime?), and I can also set it to any value other than null, and the debug line confirms the correct properties are set, they're just not saved. I think I must be missing something.

Thanks for any help.

A: 

You are creating a new package (with the id of an existing package), which you are calling "existing". You are then attaching it as if it was an existing package. You should load this package from the database and then attach it.

Shiraz Bhaiji
The method I use does work for changes to any value other than the default value. I think it's because the object is detached the re-attached, but it was discussed at http://stackoverflow.com/questions/1612655/entity-framework-updating-with-related-entity
Echilon
+1  A: 

Turns out what I needed to do was manually mark each prooerty in the new item as modified.

/// <summary>
/// Sets all properties on an object to modified.
/// </summary>
/// <param name="context">The context.</param>
/// <param name="entity">The entity.</param>
private static void SetAllPropertiesModified(ObjectContext context, object entity) {
    var stateEntry = context.ObjectStateManager.GetObjectStateEntry(entity);
    // Retrieve all the property names of the entity
    var propertyNames = stateEntry.CurrentValues.DataRecordInfo.FieldMetadata.Select(fm => fm.FieldType.Name);
    foreach(var propertyName in propertyNames) {// Set each property as modified
        stateEntry.SetModifiedProperty(propertyName);
    }
}
Echilon