Reputation: 7754
When using the OData Client (.NET) for v4 to create/post a new entity we are not getting the auto-generated (auto-incremented) ID/Key back from the service. When we create the new entity, we have no ID assigned (it is an 'int' so the value is '0'). After calling SaveChanges the result JSON response has the new auto-assigned id (e.g. '4662'). The issue is that the Entity on the client side still has '0' for its ID (it's not mapped back to the orig. entity).
I also opened the issue on GitHub: https://github.com/OData/odata.net/issues/775
The newly created (and saved) entity will have the ID updated to match the server-side response (JSON) that came back to the client.
JSON response form the server-side has the correct ID, but the Entity on the client-side is never updated with this new information.
Upvotes: 3
Views: 1060
Reputation: 2090
In order to support your scenario, some requirements want to be met. For a full reference, see my sample project at GitHub.
Given a model:
public class Item {
[Key] //define as key
[DatabaseGenerated(DatabaseGeneratedOption.Identity)] //used by EF to auto generate Ids and mapping them back on inserts
public int Id { get; set; }
[Required(AllowEmptyStrings = false)]
public string Name { get; set; }
}
An EntityFramwork-DbContext:
public class SampleContext : DbContext {
public SampleContext()
: base("name=SampleContext") {
}
public DbSet<Person> Persons { get; set; }
public DbSet<Item> Items { get; set; }
}
A straight-forward OData-configuration:
var builder = new ODataConventionModelBuilder();
builder.EntitySet<Person>("Persons");
builder.EntitySet<Item>("Items");
config.MapODataServiceRoute("ODataRoute", "odata", builder.GetEdmModel());
and a corresponding ODataController:
public class ItemsController : ODataController {
private readonly SampleContext _Db;
public ItemsController() {
_Db = new SampleContext();
}
...
[ResponseType(typeof(CreatedODataResult<Item>))]
public IHttpActionResult Post(Item p) {
if (!ModelState.IsValid)
return BadRequest(ModelState);
var inserted = _Db.Items.Add(p);
_Db.SaveChanges();
//return entity with any server side changes. This would also work for other DB-generated columns.
return Created(inserted);
}
}
Should produce the desired result:
public void AddingItemTransportsServerGeneratedIdBackToClientSideModel() {
var item = new Item() {
Name = Guid.NewGuid().ToString()
};
var container = new Container(new Uri("http://localhost/ODataAutoId/odata"));
container.AddToItems(item);
container.SaveChanges();
var actual = item.Id;
var unexpected = 0;
Assert.AreNotEqual(unexpected, actual);
}
Your actual implementation might vary or miss some of the requirements. In order to help in your particular scenarion, provide more details, as stated in my comment.
Upvotes: 1