• 【EFCORE笔记】变更追踪策略与原理


    当利用上下文对实体进行增删改查时,EF是如何生成正确 SQL 命令的?又是如何知道哪些属性值发生了改变呢?答案是利用变更追踪机制。

    Snapshot 快照式变更追踪(默认)

    DetectChanges 方法的用途

    下列的代码中我们查询了一个Blog 实体,同时修改 Url 属性,最终对 Url 的改变被保存到了数据库。

    Blog blog = context.Blogs.Find(1);
     blog.Url = "www.baidu.com"; 
    context.SaveChanges();
    

      

    当从数据库进行查询数据时,上下文便捕获了每个实体属性的快照(数据库值,原始值,当前值),当调用   SaveChanges 时,在内部会自动调用 DetectChanges 方法,此方法将扫描上下文中所有实体,并比较当前属性值和存储在快照中的原始属性值,如果被找到的属性值发生了改变,此时EF将会与数据库进行交互,进行数据更新。

    EntityEntry<Blog> entry = context.Entry(blog);

    查询当前数据库中的值:string database = entry.GetDatabaseValues().GetValue<string>(propName); 首次从数据库中查询的值:string original = entry.OriginalValues.GetValue<string>(propName); 获取此实体的当前属性值:string current = entry.CurrentValues.GetValue<string>(propName);

    默认情况下 DetectChanges 方法会在在很多场景下自动调用,并不需要手动去调用,比如以下场景就会自动调用。

    会导致自动调用 DetectChanges 方法: Find、Local、Remove、Add、UpdateAttach、SaveChanges 和 Entry 等。

    关闭自动调用 DetectChanges 方法

    context.ChangeTracker.AutoDetectChangesEnabled = false;
    
    Blog blog = context.Blogs.Find(1); 
    
    Console.WriteLine(context.Entry(blog).State);
    
    blog.Url = "www.baidu.com";
    
    Console.WriteLine(context.Entry(blog).State);
    
    context.ChangeTracker.DetectChanges(); 
    
    Console.WriteLine(context.Entry(blog).State);
    
    Console.WriteLine(context.Entry(blog).State);
    

      

    使用属性变更通知接口

    实现 INotifyPropertyChanged、INotifyPropertyChanging 和 INotifyCollectionChanged 接口。

    谈谈 INotifyPropertyChanged 的实现

    ObservableCollection 和 ObservableHashSet 实现了 INotifyCollectionChanged 接口。可使用 AOP 扩展拦截方法或属性的调用:Unity.Interception 动态拦截。

  • 相关阅读:
    vs2013 调用只有dll文件的动态库(一)
    剑指offer 34.二叉树中和为某一值的路径
    JQuery中bind和unbind函数与onclick绑定事件区分
    实现 select中指定option选中触发事件
    页面中的checkbox多选值获取
    页面中href链接的碰撞
    页面中onclick事件引号问题
    页面间传输参数(两种传参方法)
    js的非空校验
    时间控件,选择日期
  • 原文地址:https://www.cnblogs.com/lbonet/p/14608793.html
Copyright © 2020-2023  润新知