user6052905 user6052905 - 4 months ago 56
Ajax Question

when i update database with Ajax in ModelState of mvc

I going to update database when users clicked on Checkbox in Index View
this is my View Code (in view changed DispalyFor to CheckBoxFor)

@Html.CheckBoxFor(modelItem => item.Active, new
{
data_url = Url.Action("Subscribe", "Home"),
data_id = item.Id,
})


and in ajax Write this

<script>
$(function() {
//var id, Active;
$('#item_Active').change(function () {
var ch = $(this).is(":checked");

var data = { 'id': $(this).data('id'), 'Active': ch };

//data[$(this).attr('name')] = $(this).is(':checked');
$.ajax({
url: $(this).data('url'),
type: 'POST',
data: data,
success: function() {
alert("Ok");
},
error: function(e) {
alert(e.toString());
}
});
});
});

</script>


and my controller is in Home Action

[HttpPost]
public ActionResult Subscribe([Bind(Include = "id,Active")]Subscribe subscribe)
{

if (ModelState.IsValid)
{
var sub = db.Subscribes.FirstOrDefault(x => x.Id == subscribe.Id);
db.Entry(subscribe).State = EntityState.Modified;

db.SaveChanges();
}
return RedirectToAction("Index");
}


when click on my checkbox get this error

System.InvalidOperationException: Attaching an entity of type '' failed because another entity of the same type already has the same primary key value. This can happen when using the 'Attach' method or setting the state of an entity to 'Unchanged' or 'Modified' if any entities in the graph have conflicting key values. This may be because some entities are new and have not yet received database-generated key values. In this case use the 'Add' method or the 'Added' entity state to track the graph and then set the state of non-new entities to 'Unchanged' or 'Modified' as appropriate.

Answer

When you load an entity from DB, EF tracks that entity for any changes. The problem is you want to make EF to track another instance of that type(subscribe in your case), with exactly the same Id of the old one(sub in your case).

As EF recognizes the objects by their Ids it cannot have two instance of a type with the same Id. So one possible way is to modify to just modify the old one:

var sub = db.Subscribes.FirstOrDefault(x => x.Id == subscribe.Id);
sub.Active = subscribe.Active;
db.SaveChanges();
Comments