Saaman
Saaman

Reputation: 598

Cannot save modified entity and new entity at the same time

Let's imagine this EF model :

public class Person
{
    [Key]
    public int Id {get; set; }

    public string Name { get; set; }
    public string FirstName { get; set; }
    public int Age { get; set; }

    [InverseProperty("Person")]
    public ICollection<Address> Addresses { get; set; }

}

public class Address
{
    [Key]
    public int Id {get; set; }

    public int Number { get; set; }
    public string Street { get; set; }
    public string City { get; set; }

    public int PersonId { get; set; }

    [ForeignKey("PersonId")]
    [InverseProperty("Adresses")]
    public Person Person { get; set; }
}

A Person can have many Address.

I have a page in my application where I can manage Person and Address at the same time. In this page, I can create a Person and many Address in a single Breeze saveChanges() call.

It works fine, except when I try to modify Person properties and add a new Address at the same time.

This is the kindof JObject that Breeze Web API controller is receiving :

{
  "entities": [
    {
      "Id": -1,
      "PersonId": 3,
      "City": "Seattle",
      "Street": "Main Av",
      "Number": 1540,
      "entityAspect": {
        "entityTypeName": "Address:#MyApp.Models",
        "defaultResourceName": "Addresses",
        "entityState": "Added",
        "originalValuesMap": {},
        "autoGeneratedKey": {
          "propertyName": "Id",
          "autoGeneratedKeyType": "Identity"
        }
      }
    },
    {
      "Id": 3,
      "Name": "Doe",
      "FirstName": "John",
      "Age": 32,
      "entityAspect": {
        "entityTypeName": "Person:#MyApp.Models",
        "defaultResourceName": "Persons",
        "entityState": "Modified",
        "originalValuesMap": {
          "FirstName": "William"
        },
        "autoGeneratedKey": {
          "propertyName": "Id",
          "autoGeneratedKeyType": "Identity"
        }
      }
    }
  ],
  "saveOptions": {}
}

When calling contextProvider.SaveChanges() server-side, EF is complaining and refuse to accept my changes:

AcceptChanges cannot continue because the object's key values conflict with another object in the ObjectStateManager. Make sure that the key values are unique before calling AcceptChanges.

I have no idea what is going on, but it seems the way Breeze save these entities leads to duplicated entities in Entity Framework state manager.

Does anyone have an idea on how to fix / work around this? Is it a bug in Breeze, or someting I'm not doing correctly?

By the way, I'm running with Breeze 1.4.2 and Entity Framework 5.0.0

Upvotes: 3

Views: 505

Answers (1)

Saaman
Saaman

Reputation: 598

I found an answer to my issue.

Actually, I was performing some validations before saving, using Breeze's BeforeSaveEntities delegate. Thing is, if you are retrieving an entity from DBContext during these validations and that the same entity is being saved later as part of the JObject submitted to Breeze controller, you run into the issue.

The workaround I use is to perform these validations as AfterSaveEntities hooks instead, and tell Breeze to use a transaction.

Upvotes: 3

Related Questions