简体   繁体   English

EF Core - SaveChanges 上没有数据库更新

[英]EF Core - no database update on SaveChanges

today I've got a little surprised that my SaveChanges() method of DbContext didn't work as expected.今天,我对 DbContext 的SaveChanges()方法没有按预期工作感到有点惊讶。

Here is the method I used to get user data from Db:这是我用来从 Db 获取用户数据的方法:

        public async Task<UserModel> GetUserByIdAsync(string Id, bool editMode)
        {
            if (editMode) return await UserDbContext.Users.FirstOrDefaultAsync(usr => usr.UserId == Id);
            else return await UserDbContext.Users.AsNoTracking().FirstOrDefaultAsync(usr => usr.UserId == Id);
        }

And here is the method that was supposed to update the entity in Db:这是应该更新 Db 中的实体的方法:

        public async Task<bool> UpdateUserDataByAsync(UserModel updatedUser, ClaimsPrincipal currentUser)
        {
            var user = await GetUserByIdAsync(updatedUser.UserId, true);
            user = updatedUser;
            return await UserDbContext.SaveChangesByAsync(currentUser) > 0;
        }

Also SaveChangesByAsync method is just overriden SaveChanges() to automatically update some Db columns like UpdatedBy :此外, SaveChangesByAsync方法只是覆盖SaveChanges()以自动更新一些 Db 列,如UpdatedBy

public async Task<int> SaveChangesByAsync(ClaimsPrincipal userPrincipal,
                                         CancellationToken cancellationToken = new CancellationToken())
        {
            try
            {
                DateTime now = DateTime.UtcNow;
                var entries = ChangeTracker
                    .Entries()
                    .Where(e => e.Entity is BaseModel && (
                            e.State == EntityState.Added
                            || e.State == EntityState.Modified));

                foreach (var entityEntry in entries)
                {
                    ((BaseModel)entityEntry.Entity).UpdatedDate = now;
                    ((BaseModel)entityEntry.Entity).UpdatedBy = userPrincipal.FindFirstValue("UserId") ?? "Anonymous";

                    if (entityEntry.State == EntityState.Added)
                    {
                        ((BaseModel)entityEntry.Entity).CreatedDate = now;
                        ((BaseModel)entityEntry.Entity).CreatedBy = userPrincipal.FindFirstValue("UserId") ?? "Anonymous";
                    }
                }

                return await base.SaveChangesAsync(cancellationToken);
            }
            catch (TaskCanceledException)
            {
                return await Task.FromCanceled<int>(cancellationToken);
            }

        }

Eventually I overcame this problem by changing UpdateUserDataByAsync to the following content:最终我通过将UpdateUserDataByAsync更改为以下内容克服了这个问题:

            UserDbContext.Entry(await GetUserByIdAsync(updatedUser.UserId, true)).CurrentValues.SetValues(updatedUser);
            return await UserDbContext.SaveChangesByAsync(currentUser) > 0;

But I would like to ask you why the initial version didn't work?但是我想问你为什么初始版本不起作用? Since the user was pulled without AsNoTracking() modifier, shouldn't the context keep tracking any change, which in this case was a simple replacement of user data with updatedUser data?由于用户在没有AsNoTracking()修饰符的情况下被拉取,上下文不应该继续跟踪任何更改,在这种情况下,这只是用更新的用户数据简单地updatedUser user数据吗?

Thank you!谢谢!

You can make your code much simplier:您可以使代码更简单:

public async Task<bool> UpdateUserDataByAsync(UserModel updatedUser, ClaimsPrincipal currentUser)
        {
 UserDbContext.Entry(updatedUser).State = EntityState.Modified;
 return await UserDbContext.SaveChangesByAsync(currentUser) > 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM