zoukankan      html  css  js  c++  java
  • EF的 NoTracking 的一些记录

    NoTracking官方解释

    跟踪与非跟踪查询

    跟踪行为可控制 Entity Framework Core 是否将有关实体实例的信息保留在其更改跟踪器中。 如果已跟踪某个实体,则该实体中检测到的任何更改都会在 SaveChanges() 期间永久保存到数据库。Entity Framework Core 还会修正从跟踪查询中获取的实体与先前已加载到 DbContext 实例中的实体两者之间的导航属性。 

      

    可以理解为:

    DbContext如果配置为TrackAll。

    则DbContext会跟踪返回的实体实例,记录增删改查的跟踪记录,并自动整合变化,推送Diff Change保留至数据库。

    DbContext如果配置为NoTracking。

    则DBContext不会跟踪实体变化(不再自动标记实体变化,但手动标记仍有效),并不自动修正变化。

    1.对增删改查的影响

    NoTracking  不允许 相同的实体被标记多次

    也就是 Attach 的实体必须有不同的标记。

    但TrackAll不会有此问题,因为会自动修正2个实体标记

    2.查询缓存

    public void Test()
            {
                var id = st.T_User.Select(o => o.ID).FirstOrDefault();
    
                using (FLFPermissionEntities ent = dbr.CreateContext<FLFPermissionEntities>())
                {
                    using (FLFPermissionEntities sub1 = new FLFPermissionEntities())
                    {
                        var jm = sub1.FlexUpdate<T_User>(o => o.Name = "lcc", o => o.ID == id);
                        if (jm.HasMsg())
                            Assert.Fail(jm.msg);
                    }
    
                    var user21 = ent.T_User.FirstOrDefault(o => o.ID == id);
    
                    Console.WriteLine($"TrackAllDBContext 第一次读取:{user21.Name}");
    
                    using (FLFPermissionEntities sub2 = new FLFPermissionEntities())
                    {
                        Console.WriteLine($"改变Name的值为lcc2");
                        var jm = sub2.FlexUpdate<T_User>(o => o.Name = "lcc2", o => o.ID == id);
                        if (jm.HasMsg())
                            Assert.Fail(jm.msg);
                    }
    
                    var user22 = ent.T_User.FirstOrDefault(o => o.ID == id);
                    Console.WriteLine($"TrackAllDBContext 第二次读取:{user22.Name}");
                }
    
                using (FLFPermissionEntities ent = dbr.CreateReadContext<FLFPermissionEntities>())
                {
                    using (FLFPermissionEntities sub1 = new FLFPermissionEntities())
                    {
                        var jm = sub1.FlexUpdate<T_User>(o => o.Name = "lcc", o => o.ID == id);
                        if (jm.HasMsg())
                            Assert.Fail(jm.msg);
                    }
    
    
                    var user21 = ent.T_User.FirstOrDefault(o => o.ID == id);
    
                    Console.WriteLine($"NoTrackDBContext 第一次读取:{user21.Name}");
    
                    using (FLFPermissionEntities sub2 = new FLFPermissionEntities())
                    {
                        Console.WriteLine($"改变Name的值为lcc2");
                        var jm = sub2.FlexUpdate<T_User>(o => o.Name = "lcc2", o => o.ID == id);
                        if (jm.HasMsg())
                            Assert.Fail(jm.msg);
                    }
    
                    var user22 = ent.T_User.FirstOrDefault(o => o.ID == id);
                    Console.WriteLine($"NoTrackDBContext 第二次读取:{user22.Name}");
    
    
                }
            }

    NoTrack的结果是正确的,TrackAll的结果与实际结果不同

    会发现 TrackAll的 2次查询 结果是一样的,而且TrackAll的第二次读取时已经访问了数据,但出来的结果 还是lcc  并不是lcc2。

    所以TrackAll 会从数据库读取数据后,根据跟踪记录里的数据信息,覆盖数据库中读取的结果

     DbContext 认为 跟踪记录的数据必须统一且数据已跟踪记录为准

  • 相关阅读:
    学习笔记-php图像等比例剪裁-2016.4.7
    学习日记-2016.3.31
    学习日记--2016.3.30
    I/O扩展篇(基于74HC164/74HC165)
    Visual SVN Server启动失败0x8007042a错误
    CC3000 主机驱动API介绍
    CC3000 SPI接口编程介绍
    struct和typedef struct彻底明白了
    MSP430学习笔记:UART
    DWORD类型的IP地址转换为CString字符串
  • 原文地址:https://www.cnblogs.com/shikyoh/p/10918301.html
Copyright © 2011-2022 走看看