reza.nadrian
reza.nadrian

Reputation: 1

Update context in SQL Server from ASP.NET Core 2.2

_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());
    }
}

Upvotes: 0

Views: 788

Answers (1)

jpgrassi
jpgrassi

Reputation: 5742

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

Upvotes: 1

Related Questions