This code worked fine when I used model first aproach. And stoped saving a Vote if it is a new Vote(). I guess model first generated classes used some ‘magic’ on property setters i thought that’s what we put virtual in code first properties for. Is there a way to make it work old style? or should i search and replace and tie a new object to graph in some other way?
public ActionResult Vote(int id, string votetype)
{
int userid = ViewBag.User.Id;
var pub = DB.Publications.Single(p => p.Id == id);
var votes = pub.Votes.SingleOrDefault(v => v.MemberId == userid) ??
new Vote
{
MemberId = userid,
Publication = pub
};
DB.SaveChanges();
return RedirectToAction("Full", new { id = id });
}
It worked before but it was written in a bad way from the beginning because it really uses some internal magic and in your example it can be called side effect. You should avoid code which does some logic through side effects.
The magic is automatic fix up of navigation properties. You create a new
Voteand set itsPublicationnavigation property withPublicationinstance attached to the context. In such case EF will fix relations for you and it internally also addsVotetoPublication. Because of the fix up the newVotewill become tracked as well (as a new entity).Your custom classes used in the code first doesn’t have fix up methods unless you write it manually or copy them from code generated by POCO T4 template used in model and database first. Without fix up the new
Votewill not be added to the context andSaveChangeswill not perform any modification.Use @Diego’s code to fix your method.