0
_context.Update(v) ;
_context.SaveChanges();

When I use this code then SQL Server adds a new record instead of updating the current context

[HttpPost]
public IActionResult PageVote(List<string> Sar)
{
    string name_voter = ViewBag.getValue = TempData["Namevalue"];

    int count = 0;

    foreach (var item in Sar)
    {
        count = count + 1;
    }

    if (count == 6)
    {
        Vote v = new Vote()
                 {
                    VoteSarparast1 = Sar[0],
                    VoteSarparast2 = Sar[1],
                    VoteSarparast3 = Sar[2],
                    VoteSarparast4 = Sar[3],
                    VoteSarparast5 = Sar[4],
                    VoteSarparast6 = Sar[5],
                 };

        var voter = _context.Votes.FirstOrDefault(u => u.Voter == name_voter && u.IsVoted == true);

        if (voter == null)
        {
            v.IsVoted = true;
            v.Voter = name_voter;
            _context.Add(v);
            _context.SaveChanges();

            ViewBag.Greeting = "رای شما با موفقیت ثبت شد";
            return RedirectToAction(nameof(end));
        }

        v.IsVoted = true;
        v.Voter = name_voter;

        _context.Update(v);
        _context.SaveChanges();

        return RedirectToAction(nameof(end));
    }
    else
    {
        return View(_context.Applicants.ToList());
    }
}
5
  • Welcome to SO :). We need more code in order to help you. Especially, where does v comes from? Is it a parameter? The problem you are facing is: The DbContext is not aware of v, that means it is not tracking it. When you call Update it checks internally and say: Hum.. I don't know this guy, so I better insert it. To fix, you have to load it first, then call Update. Commented Apr 7, 2019 at 19:30
  • public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options) { } public DbSet<Role> Roles { get; set; } public DbSet<User> Users { get; set; } public DbSet<Vote> Votes { get; set; } public DbSet<Applicant> Applicants { get; set; } } //// public HomeController(DatabaseContext context) { _context = context; } ...... //// Vote v = new Vote() { .. } Commented Apr 7, 2019 at 19:34
  • That's why then. v is a new instance, there's no way the DbContext can update that without you telling it to. Also, v has to have an Id, so the DbContext can find it. Please also put the code in your question, not in the comments as it is hard to read. Commented Apr 7, 2019 at 19:37
  • _context.SaveChanges() tracks all changes, when changes have done on an entity, don't need to call _context.Update(), _context.SaveChanges() is efficient and your entity will be updated, please notice to the Entity Framework Update Commented Apr 8, 2019 at 6:42
  • @reza.nadrian make sure to mark my answer as accepted if it helped you solve the issue. That's how you "thank me", with fake internet points. :D Commented Apr 8, 2019 at 8:38

1 Answer 1

1

You need to tell the DbContext about your entity. If you do var vote = new Vote() vote has no Id. The DbContext see this and thinks you want to Add a new entity, so it simply does that. The DbContext tracks all the entities that you load from it, but since this is just a new instance, it has no idea about it.

To actually perform an update, you have two options:

1 - Load the Vote from the database in some way; If you get an Id, use that to find it.

// Loads the current vote by its id (or whatever other field..)
var existingVote = context.Votes.Single(p => p.Id == id_from_param);

// Perform the changes you want..
existingVote.SomeField = "NewValue";                

// Then call save normally.
context.SaveChanges();

2 - Or if you don't want to load it from Db, you have to manually tell the DbContext what to do:

// create a new "vote"...
var vote = new Vote
{
    // Since it's an update, you must have the Id somehow.. so you must set it manually
    Id = id_from_param,

    // do the changes you want. Be careful, because this can cause data loss!
    SomeField = "NewValue"
};

// This is you telling the DbContext: Hey, I control this entity. 
// I know it exists in the DB and it's modified
context.Entry(vote).State = EntityState.Modified;

// Then call save normally.
context.SaveChanges();

Either of those two approaches should fix your issue, but I suggest you read a little bit more about how Entity Framework works. This is crucial for the success (and performance) of your apps. Especially option 2 above can cause many many issues. There's a reason why the DbContext keep track of entities, so you don't have to. It's very complicated and things can go south fast.

Some links for you: ChangeTracker in Entity Framework Core Working with Disconnected Entity Graph in Entity Framework Core

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.