• Entity Framework 更新失败,调试后发现是AsNoTracking的原因


    public override int SaveChanges()
            {
                var changedEntities = ChangeTracker.Entries().Where(e => e.State == EntityState.Added || e.State == EntityState.Modified).ToList();
                var now = DateTime.Now;
                changedEntities.ForEach(e =>
                {
                    if (e.State == EntityState.Added)
                    {
                        var createTimeProperty = e.Entity.GetType().GetProperty("CreateTime");
                        var createUserIdProperty = e.Entity.GetType().GetProperty("CreateUserId");
                        var createUserNameProperty = e.Entity.GetType().GetProperty("CreateUserName");
    
                        if (createTimeProperty != null)
                        {
                            createTimeProperty.SetValue(e.Entity, now);
                        }
                        if (createUserIdProperty != null)
                        {
                            createUserIdProperty.SetValue(e.Entity, InternalContext.UserId);
                        }
                        if (createUserNameProperty != null)
                        {
                            createUserNameProperty.SetValue(e.Entity, InternalContext.UserName);
                        }
    
                        var updateTimeProperty = e.Entity.GetType().GetProperty("UpdateTime");
                        var updateUserIdProperty = e.Entity.GetType().GetProperty("UpdateUserId");
                        var updateUserNameProperty = e.Entity.GetType().GetProperty("UpdateUserName");
    
                        if (updateTimeProperty != null)
                        {
                            updateTimeProperty.SetValue(e.Entity, now);
                        }
                        if (updateUserIdProperty != null)
                        {
                            updateUserIdProperty.SetValue(e.Entity, InternalContext.UserId);
                        }
                        if (updateUserNameProperty != null)
                        {
                            updateUserNameProperty.SetValue(e.Entity, InternalContext.UserName);
                        }
                    }
                    else if (e.State == EntityState.Modified)
                    {
                        var isDeleteProperty = e.Entity.GetType().GetProperty("IsDelete");
                        if (isDeleteProperty != null && (bool)isDeleteProperty.GetValue(e.Entity))
                        {
                            var deleteTimeProperty = e.Entity.GetType().GetProperty("DeleteTime");
                            var deleteUserIdProperty = e.Entity.GetType().GetProperty("DeleteUserId");
                            var deleteUserNameProperty = e.Entity.GetType().GetProperty("DeleteUserName");
    
                            if (deleteTimeProperty != null)
                            {
                                deleteTimeProperty.SetValue(e.Entity, now);
                            }
                            if (deleteUserIdProperty != null)
                            {
                                deleteUserIdProperty.SetValue(e.Entity, InternalContext.UserId);
                            }
                            if (deleteUserNameProperty != null)
                            {
                                deleteUserNameProperty.SetValue(e.Entity, InternalContext.UserName);
                            }
                        }
                        else
                        {
                            var updateTimeProperty = e.Entity.GetType().GetProperty("UpdateTime");
                            var updateUserIdProperty = e.Entity.GetType().GetProperty("UpdateUserId");
                            var updateUserNameProperty = e.Entity.GetType().GetProperty("UpdateUserName");
    
                            if (updateTimeProperty != null)
                            {
                                updateTimeProperty.SetValue(e.Entity, now);
                            }
                            if (updateUserIdProperty != null)
                            {
                                updateUserIdProperty.SetValue(e.Entity, InternalContext.UserId);
                            }
                            if (updateUserNameProperty != null)
                            {
                                updateUserNameProperty.SetValue(e.Entity, InternalContext.UserName);
                            }
                        }
                    }
                });
    
                return base.SaveChanges();
            }

    先看以上代码,我们封装了一个SaveChanges的方法,用来提交实体的修改或插入操作,这个操作有个好处就是不用写事务,如果你需要插入多张表,并且是要么全部成功,要么全部失败,那使用这个方法就很方便了。

    不过今天遇到一个更新的问题,始终没有报错,但就是无法更新。

    后来调试代码,发现一个很关键的地方:AsNoTracking()

    针对查询,在一些情况下,我们只需要返回一个只读的数据就可以,并不会对数据记录进行任何的修改。

    这种时候不希望Entity Framework进行不必要的状态变动跟踪,可以使用Entity Framework(EFCore中也有哦)的AsNoTracking方法来查询返回不带变动跟踪的查询结果

    由于是无变动跟踪,所以对返回的数据的没有进行任何修改,在SaveChanges()时,都不会提交到数据库中。

    所以,我上图中的代码虽然下面修改了IsDelete=true,但是我在查询的时候已经加入了AsNoTracking,当我SaveChange的时候,这个修改并不会被提交,所以无法完成更新。

    我们在做数据集合查询显示,而又不需要对集合修改并更新到数据库的时候,

    一定不要忘记加上AsNoTracking。

    如果查询过程做了select映射不需要加AsNoTracking

    如:db.user.Where(t=>t.Name.Contains("小明")).select(t=>new (t.Name,t.Age)).ToList();

    更多精彩内容,请关注我的V信公众号:程序员不帅哥
  • 相关阅读:
    CYQ.Data 轻量数据层之路 V4.0 版本发布
    基于MSAA的自动化封装和设计—python版(转)
    【自然框架】之鼠标点功能现(二):表单控件的“应用”—— 代码?只写需要的!
    论管理员的不作为!!!
    【自然框架】之通用权限的Demo(二):添加人员、添加账户、添加角色里面的账户以及列表的权限验证
    使用接口来统一控件的取值、赋值和初始化
    【自然框架】之通用权限(八):权限到字段(列表、表单、查询)
    辩论赛 VS 讨论组
    【自然框架】表单控件 之 一个表单修改多个表里的记录
    【自然框架】之“解耦”初探
  • 原文地址:https://www.cnblogs.com/Mr-Worlf/p/14184996.html
Copyright © 2020-2023  润新知