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
开发者_Go百科 {
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 Vote
and set its Publication
navigation property with Publication
instance attached to the context. In such case EF will fix relations for you and it internally also adds Vote
to Publication
. Because of the fix up the new Vote
will 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 Vote
will not be added to the context and SaveChanges
will not perform any modification.
Use @Diego's code to fix your method.
Nowhere in that code are you telling EF to persist the new vote.
Change the line where you get/create the vote to:
var vote = pub.Votes.SingleOrDefault(v => v.MemberId == userid);
if (vote == null)
pub.Votes.Add(new Vote
{
MemberId = userid,
Publication = pub
});
精彩评论