Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dbContext.<Entity>.Update() is creating new records #3890

Closed
DiegoZoracKy opened this issue Nov 25, 2015 · 12 comments
Closed

dbContext.<Entity>.Update() is creating new records #3890

DiegoZoracKy opened this issue Nov 25, 2015 · 12 comments
Labels
closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. type-bug
Milestone

Comments

@DiegoZoracKy
Copy link

When i do something like:

var e = new Entity();
e.Id = 100;
e.Name = "Name 100";
dbContext.Entities.Update(e);
dbContext.SaveChanges();

a new record is created.

Is this the correct behaviour?

@rowanmiller
Copy link
Contributor

@DiegoZoracKy it should attempt to update an existing record, not insert a new one. Can you share a full code listing that we can use to reproduce the issue? (i.e. the code for Entity and your context)

@DiegoZoracKy
Copy link
Author

@rowanmiller i've created something simple to show the case. See:

using Microsoft.AspNet.Mvc;
using System.Linq;
using Microsoft.Data.Entity;
using Newtonsoft.Json.Linq;

public class TestUpdate
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class MyContext : DbContext
{
    public DbSet<TestUpdate> TestUpdates { get; set; }      
}           

[Route("api/[controller]")]
public class TestController : Controller
{
    private MyContext dbContext;

    public TestController(MyContext context)
    {
        dbContext = context;
    }

    [HttpGet]
    public IActionResult Get()
    {
        var e = new TestUpdate();
        e.Name = "Name 100";
        dbContext.TestUpdates.Update(e);
        dbContext.SaveChanges();

        return new ObjectResult(dbContext.TestUpdates.AsNoTracking().ToList());
    }
}   

Every time you hit api/test (GET) a new record will be saved.

@DiegoZoracKy
Copy link
Author

@rowanmiller i've found what it seems to be another weird behavior on Update method. Let's suppose that in my previous example, AnotherClass exists on the project and it makes a reference to TestUpdate, like:

    public class AnotherClass
    {
        public int Id { get; set; }
        public virtual List<TestUpdate> TestUpdate { get; set; }
    }

Thinking about SQLServer, this will create a column AnotherClassId on the TestUpdate Table, with a reference to records on AnotherClass, right?

The problem is that when i do .Update on TestUpdate, this reference is being set to NULL.

@rowanmiller
Copy link
Contributor

@DiegoZoracKy regarding the first issue you reported...

This situation is arising because TestUpdate.Id is assigned a value of 0. The fact that we are implying this means it is added (even though you called Update) is a bug and we will fix it. That said, do you actually have an existing row in the database with an Id of zero... or is that just a coding error where you are not setting the key property?

If having a key value of zero is a legitimate requirement, then you can workaround this until we fix the bug by explicitly setting the state (rather than calling Update).

dbContext.Entry(e).State = EntityState.Modified;

@rowanmiller
Copy link
Contributor

@DiegoZoracKy can you open a new issue for the second case you mentioned (and include code that demonstrates the issue again).

@DiegoZoracKy
Copy link
Author

@rowanmiller No, id 0 is not a requirement of my software. I've created this simple example for you to see that the Update method is creating new records. Good that it is a Bug and not its correct behavior.

I will create a new issue for sure, within some hours. This current issue is something easy to be avoided, just bringing a performance penalty by checking if the record exists for real before update it. But this last one can be a huge problem.

@rowanmiller
Copy link
Contributor

@DiegoZoracKy just to be clear, it only inserts a row if the key is set to zero. If it is set to anything else then it will correctly update it.

i.e. this code

var e = new TestUpdate();
e.Name = "Name 100";
e.Id = 5;
dbContext.TestUpdates.Update(e);
dbContext.SaveChanges();

Produces this SQL

exec sp_executesql N'SET NOCOUNT OFF;
UPDATE [TestUpdate] SET [Name] = @p1
WHERE [Id] = @p0;
SELECT @@ROWCOUNT;
',N'@p0 int,@p1 nvarchar(4000)',@p0=5,@p1=N'Name 100'

Not saying that it's not a bug... but just that you'll only see the insert behavior if you are attempting to update an entity with a key set to zero.

@DiegoZoracKy
Copy link
Author

@rowanmiller i just tried setting a value to Id, like that:

var e = new TestUpdate();
e.Id = 100;
e.Name = "Name 100";
dbContext.TestUpdates.Update(e);
dbContext.SaveChanges();

And a new record was created. But for this test i used inMemory (EntityFramework.InMemory: 7.0.0-rc1-final) instead of SQL Server.

@DiegoZoracKy
Copy link
Author

@rowanmiller And, a new issue about the reference being lost during Update, that i commented above: #3948

@rowanmiller
Copy link
Contributor

@DiegoZoracKy I was able to reproduce that issue with InMemory. It's different from the original bug on this issue (which is already fixed), so I opened #3953 for the new issue.

@DiegoZoracKy
Copy link
Author

Thanks @rowanmiller. I will track this new issue.

@rowanmiller rowanmiller reopened this Dec 3, 2015
@rowanmiller
Copy link
Contributor

Re-opening as we still need this to track the issue where the entity being passed to Update is marked as added if it has no key value assigned.

@rowanmiller rowanmiller modified the milestones: 7.0.0-rc2, 7.0.0 Dec 3, 2015
ajcvickers added a commit that referenced this issue Jan 20, 2016
Issue #3890

When a graph of entities is given to Attach or Update, the state of those entities is set to Unchanged/Modified unless the entity is using key value generation and the key value is not set, in which case the state is set to Added. But for the actual entity passed to these methods (as opposed to additional entities discovered in the graph) we decided that the state should be the requested state regardless of whether or not the key value is set.
ajcvickers added a commit that referenced this issue Jan 26, 2016
Issue #3890

When a graph of entities is given to Attach or Update, the state of those entities is set to Unchanged/Modified unless the entity is using key value generation and the key value is not set, in which case the state is set to Added. But for the actual entity passed to these methods (as opposed to additional entities discovered in the graph) we decided that the state should be the requested state regardless of whether or not the key value is set.
@ajcvickers ajcvickers removed this from the 1.0.0-rc2 milestone Oct 15, 2022
@ajcvickers ajcvickers added the closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. label Oct 15, 2022
@ajcvickers ajcvickers added this to the 1.0.0 milestone Oct 15, 2022
@ajcvickers ajcvickers removed their assignment Sep 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. type-bug
Projects
None yet
Development

No branches or pull requests

3 participants