zoukankan      html  css  js  c++  java
  • 【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 动态拦截。

  • 相关阅读:
    MVC设置默认页面
    MySQL_DBA整理
    解决git提交敏感信息(回退git版本库到某一个commit)
    并发数计算
    高并发下的 Nginx 优化与负载均衡
    PassengerNginxdebian快速部署Rails
    Linux+postfix+extmail+dovecot打造基于web页面的邮件系统
    2018.11.30软件更新公告
    2018.10.11软件更新公告
    2018.09.25软件更新公告
  • 原文地址:https://www.cnblogs.com/lbonet/p/14608793.html
Copyright © 2011-2022 走看看