• EF中的自动追踪与代理


    自动追踪

    EF框架会自动追踪实体的变化(通过比较实体的当前值与原始值)。

    默认情况下,以下方法会自动触发实体变化的追踪

    • DbSet.Find
    • DbSet.Local
    • DbSet.Remove
    • DbSet.Add
    • DbSet.Attach
    • DbContext.SaveChanges
    • DbContext.GetValidationErrors
    • DbContext.Entry
    • DbChangeTracker.Entries

    在循环添加大量实体时,可以通过关闭自动追踪功能提升性能,但在循环结束后要开启

    using (var context = new BloggingContext()) 
    { 
        try 
        { 
            context.Configuration.AutoDetectChangesEnabled = false; 
     
            // Make many calls in a loop 
            foreach (var blog in aLotOfBlogs) 
            { 
                context.Blogs.Add(blog); 
            } 
        } 
        finally 
        { 
            context.Configuration.AutoDetectChangesEnabled = true; 
        } 
    }
    

    如果没有开启自动追踪功能,当实体变化时,无法自动更新到数据库中的。可以通过使用content.ChangeTracker.DetectChanges方法手动检测

          static void Main(string[] args)
            {
                using (var db=new SchoolEntities2())
                {
                   db.Configuration.AutoDetectChangesEnabled = false;//禁用自动追踪
                    var author = db.Authors.Find(1);
                    author.Name = "112";
                    db.ChangeTracker.DetectChanges();//手动检测实体
                    Console.WriteLine(db.Entry(author).State);
                    db.SaveChanges();
                }
    
                Console.WriteLine("ok");
                Console.ReadLine( );
    

    在只读场景下,当查询大量数据时,可以通过禁用实体的追踪来提升性能

    using (var context = new BloggingContext()) 
    { 
        // Query for all blogs without tracking them 
        var blogs1 = context.Blogs.AsNoTracking(); 
     
        // Query for some blogs without tracking them 
        var blogs2 = context.Blogs 
                            .Where(b => b.Name.Contains(".NET")) 
                            .AsNoTracking() 
                            .ToList(); 
    }
    

    代理

    为 POCO 实体类型创建实例时,实体框架常常为充当实体代理的动态生成的派生类型创建实例。此代理重写实体的某些虚拟属性,从而自动执行操作。例如,此机制用于支持关系的延迟加载。

    禁止创建代理

    this.Configuration.ProxyCreationEnabled = false; 
    

    显示创建代理实例

    var blog = context.Blogs.Create(); 
    

    从代理类型获取实际实体类型

    var blog = context.Blogs.Find(1); 
    var entityType = ObjectContext.GetObjectType(blog.GetType()); 
    

    如果传递给 GetObjectType 的类型是非代理类型的实体类型的实例,则仍将返回实体的类型。这意味着,始终可以使用此方法获取实际的实体类型,而不用再检查类型是否是代理类型。

  • 相关阅读:
    [转]django自定义表单提交
    [django/mysql] 使用distinct在mysql中查询多条不重复记录值的解决办法
    [Django]下拉表单与模型查询
    [Django]模型提高部分--聚合(group by)和条件表达式+数据库函数
    [Django]模型学习记录篇--基础
    [Django]数据批量导入
    怎么让自己的本地php网站让别人访问到
    HTML Marquee跑马灯
    marquee标签详解
    apache的虚拟域名rewrite配置以及.htaccess的使用。
  • 原文地址:https://www.cnblogs.com/goodlucklzq/p/4672785.html
Copyright © 2020-2023  润新知