Search code examples
sql-serverentity-frameworkbreeze

Breeze->EF6 updating some changed columns, but not all


I've got a Breeze Context Provider talking to a EF 6.1.1, database-first, application with SQL Server that I'm having some trouble with. I can INSERT a new record, but when I update it, not all the changed columns get written to the database.

I have a generated POCO that looks like this:

public partial class Inventory
{
    public Inventory()
    {
    }

    public int Id { get; set; }
    public System.DateTime EnteredAt { get; set; }
    public string EnteredBy { get; set; }
    public string UpdatedBy { get; set; }
    public Nullable<System.DateTime> UpdatedAt { get; set; }
    public string Comment { get; set; }
}

When I go and update an entity on client side (setting Comment property) and send it to Breeze, I do some very simple sets in a EFContextProvider::BeforeSaveEntity override:

    protected override Dictionary<Type, List<EntityInfo>> BeforeSaveEntities(Dictionary<Type, List<EntityInfo>> saveMap)
    {
        // only one inventory is ever sent in
        if (saveMap.ContainsKey(typeof(Inventory)))
        {
            var source = saveMap[typeof(Inventory)].First().Entity as Inventory;

            // set up the user and time fields
            if (source.Id <= 0)
            {
                source.EnteredBy = _defaultUserName;
                source.EnteredAt = DateTime.Now;
            }
            else
            {
                source.UpdatedBy = _defaultUserName;
                source.UpdatedAt = DateTime.Now;
            }

         }
     }

But when the change gets committed, the changed UpdatedBy value never gets in to the database.

I turned on EF6 SQL logging and sure enough, the UPDATE statement completely misses the property.

UPDATE [dbo].[Inventory]
SET [Comment] = @0, [UpdatedAt] = @1
WHERE ([Id] = @2)
-- @0: '1532' (Type = AnsiString, Size = 250)
-- @1: '2/4/2016 10:32:58 PM' (Type = DateTime2)
-- @2: '100344' (Type = Int32)
-- Executing at 2/4/2016 3:33:06 PM -07:00
-- Completed in 7 ms with result: 1

Of course, UpdatedBy is NULL in the database for this update.

I can't figure out why this particular column will not do through when an 'adjacent' column, set at the same time, does. I also don't know if this is a Breeze problem or an EF problem since I can go back in and just using EF, DBContext all works fine.

I also tried deleting the table from the EDMX file and re-adding it to no avail. I re-verified that the column is in the table in the EDMX file.

As a hack, what I have to do is go back in, re-read the changed record directly, update it, then send it back.

Any advice would be appreciated.


Solution

  • Can you post the BeforeSaveEntity method and a sample manipulation of the entity on the client side into your question?

    Secondly, make sure you're updating the propertyMap for the entity info in your BeforeSave method like so:

    source.UpdatedBy = "Joe User";
    source.UpdatedAt = DateTime.Now;
    source.Comment = "1532";
    
    entityInfo.OriginalValuesMap["UpdatedBy"] = null;
    entityInfo.OriginalValuesMap["UpdatedAt"] = null;
    entityInfo.OriginalValuesMap["Comment"] = null;
    

    I'm wondering if the "UpdatedAt" property is manipulated on the client before calling saveChanges, and therefore this property would already by identified as 'Modified' in the property map.