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

Attaching entity and setting different IsModified values to different property prevent update #8265

Closed
ShaZeh opened this issue Apr 24, 2017 · 3 comments
Assignees
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

@ShaZeh
Copy link

ShaZeh commented Apr 24, 2017

I am not quite sure if this is me doing something wrong, I am pretty sure I have been using this technique without any issues for a good while. But it might be possible that I might never have noticed that some fields were not updating. It might also be possible that the update only fail under very specific circonstances.

So far I have only reproduced the issue while having two property explicitly set to false and true on the second.

Also, it seems that by simply having another entity being saved within the same transaction automatically resolved problem, the IsModified was being taken into account properly.

Steps to reproduce

  • Run the code below
  • Notice that the username will remain to "name" even though the last property is set to isModified true.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage;
using System.Data;

namespace ConsoleApplication
{
    class Program
    {
        static Context context;
        static void Main(string[] args)
        {
            Task.Run(async () => { await UpdateEntity(); }).GetAwaiter().GetResult();
        }

        static async Task UpdateEntity()
        {
            context = new Context();
            context.Database.EnsureCreated();

            var user = new Users();
            user.UserName = "name";
            user.City = "city";
            context.Add(user);
            await context.SaveChangesAsync();

            int id = user.Id;
            context.Entry(user).State = EntityState.Detached;


            user = new Users { Id = id, UserName = "New" };

            context.Attach(user);
            context.Entry(user).Property(x => x.City).IsModified = false;
            context.Entry(user).Property(x => x.UserName).IsModified = true;
            //context.Update(user);

            await context.SaveChangesAsync();

            user = await context.Users.Where(x => x.Id == id).FirstOrDefaultAsync();
            Console.WriteLine(user.UserName);
        }
    }

    public class Users
    {
        public int Id { get; set; }
        public string UserName { get; set; }
        public string City { get; set; }
    }
    public class Context : DbContext
    {
        public virtual DbSet<Users> Users { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Users>(b =>
            {
                b.HasKey(r => r.Id);

                b.Property(x => x.UserName).IsRequired();
            });
        }
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            //optionsBuilder.UseSqlServer("Server=.\\SQLEXPRESS;Initial Catalog=Test;Trusted_Connection=True;MultipleActiveResultSets=true");
            optionsBuilder.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=TestDB;Trusted_Connection=True;MultipleActiveResultSets=true");
        }
    }
}

Further technical details

EF Core version: 1.1.1
Database Provider: (e.g. Microsoft.EntityFrameworkCore.SqlServer)
Operating system: Win10
IDE: (e.g. Visual Studio 2015)
Observed on EF Core 1.1.0 as well.

Similar issues
#7798
#7227

@ajcvickers
Copy link
Member

Note for triage: Confirmed that this is a bug. Doing this works:

context.Attach(user);
context.Entry(user).Property(x => x.UserName).IsModified = true;
context.Entry(user).Property(x => x.City).IsModified = false;

But moving the IsModified = false first makes it fail:

context.Attach(user);
context.Entry(user).Property(x => x.City).IsModified = false;
context.Entry(user).Property(x => x.UserName).IsModified = true;

@ajcvickers ajcvickers self-assigned this Apr 24, 2017
@ajcvickers ajcvickers added this to the 2.0.0 milestone Apr 24, 2017
ajcvickers added a commit that referenced this issue Jun 23, 2017
Issues #7798, #8265, #8465

These issues were due to incorrect handling of nulls/conceptual nulls for required but nullable properties, in particular when attaching an entity with a required property that starts off null.
@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 Jun 26, 2017
ajcvickers added a commit that referenced this issue Jun 26, 2017
Issues #7798, #8265, #8465

These issues were due to incorrect handling of nulls/conceptual nulls for required but nullable properties, in particular when attaching an entity with a required property that starts off null.
@evgenisokolov
Copy link

It looks like it still reproducible with in-memory database. Could you please elaborate on that?

@ajcvickers
Copy link
Member

@evgenisokolov This is an old issue. If you are still running into problems, then please file a new issue and include a small, runnable project/solution or complete code listing that demonstrates the behavior you are seeing.

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