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

Timestamp/IsConcurrencyToken causes invalid UPDATE if no data modified (SQLServer) #4814

Closed
bragma opened this issue Mar 16, 2016 · 0 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

@bragma
Copy link

bragma commented Mar 16, 2016

I'm attaching a sample program causing UPDATE to fail if:

  • Model contains a [Timestamp] property (rowversion)
  • Model is saved but only the rowversion is set (and optionally other properties are set with the same values they already contained so no DB value has really to be updated).

The problem is that setting the rowversion fakes EF into thinking there is something to update, but since no property has really changed and rowversion is not saved (it is DB generated), an UPDATE with no fields to update is generated:

exec sp_executesql N'SET NOCOUNT OFF;
UPDATE [User] SET 
OUTPUT INSERTED.[RowVersion]
WHERE [UserId] = @p0 AND [RowVersion] = @p1;
',N'@p0 int,@p1 varbinary(8)',@p0=4,@p1=0x00000000000007D4

Notice the missing fields between SET and OUTPUT.

Sample code follows. Please check the last lines where the entity is updated.

namespace EFCoreTest
{
    class TestContext : DbContext
    {
        public DbSet<User> Users { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=EFCoreTestDb2;Trusted_Connection=True;");
        }
    }

    class User
    {
        public int UserId { get; set; }
        public string Name { get; set; }

        [Timestamp]
        public byte[] RowVersion { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            int id;
            byte[] version;

            using (var db = new TestContext())
            {
                db.Database.EnsureCreated();
                var user = new User { Name = "Name" };
                db.Users.Add(user);
                db.SaveChanges();
                id = user.UserId;
                version = user.RowVersion;
            }

            using (var db = new TestContext())
            {
                var user = db.Users.FirstOrDefault(u => u.UserId == id);

                // PROBLEM IS HERE
                user.Name = "Name"; // This has no effect since the value is not really changed...
                user.RowVersion = version; // This causes the problem

                db.SaveChanges();
            }
        }
    }
}
@rowanmiller rowanmiller added this to the 1.0.0 milestone Mar 22, 2016
AndriySvyryd added a commit that referenced this issue Mar 29, 2016
AndriySvyryd added a commit that referenced this issue Mar 29, 2016
AndriySvyryd added a commit that referenced this issue Mar 29, 2016
@AndriySvyryd AndriySvyryd modified the milestones: 1.0.0-rc2, 1.0.0 Apr 1, 2016
@AndriySvyryd AndriySvyryd removed their assignment Apr 1, 2016
@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
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

4 participants