【问题标题】:Disabling Entity Framework proxy creation禁用实体框架代理创建
【发布时间】:2016-11-15 16:30:32
【问题描述】:

根据我的阅读,设置ProxyCreationEnabled = false 将阻止更改跟踪和延迟加载。但是,我不清楚更改跟踪涵盖哪些内容。

如果我禁用它并从数据库中获取一个实体,对其进行更改并提交,那么这些更改将被保存。我仍然可以从 ChangeTracker 中获取修改后的条目:

ChangeTracker.Entries<IAuditable>().Where(x => x.State == EntityState.Modified).ToList()

如果我禁用了代理创建,这应该可行吗?我想禁用它,但我想清楚我正在禁用什么。

【问题讨论】:

    标签: c# entity-framework


    【解决方案1】:

    我可以确认在 EF 中将 ProxyCreationEnabled 设置为 false 不会影响更改跟踪。您实际上对这个问题很感兴趣,因为我以为我知道答案,但为了确认我创建了一个快速测试用例。

    请参见下面代表有效场景的示例代码:

    namespace EFCTTest
    {
        class Program
        {
            static void Main(string[] args)
            {
                var context = new MyContext();
                context.Tests.First().Test = "Edited";
    
                var models = context.ChangeTracker.Entries<TestModel>().Where(x => x.State == EntityState.Modified).ToList();
                foreach(var model in models)
                    Console.WriteLine($"From {model.OriginalValues["Test"]} to {model.CurrentValues["Test"]}");
    
                Console.ReadLine();
            }
        }
    
        public class MyContext : DbContext
        {
            public MyContext()
            {
                Configuration.ProxyCreationEnabled = false;
            }
    
            public DbSet<TestModel> Tests { get; set; }
        }
    
        public class TestModel
        {
            public int Id { get; set; }
            public string Test { get; set; }
        }
    }
    

    当您使用virtual 导航属性到另一个模型时,禁用代理生成应该影响的唯一事情是 EF 的延迟加载功能。 Change Tracker 是独立的,并从底层ObjectContext 本身工作。

    对于与更改跟踪相关的完整答案,可能值得注意的是AutoDetectChangesEnabled 似乎是唯一会直接影响更改跟踪功能的设置,如果您需要使用示例代码,则需要调用DetectChanges()

    【讨论】:

      【解决方案2】:

      更改跟踪和代理创建是两个不同的场景。如果您需要禁用更改跟踪,则必须按如下所示进行。

      public class YourContext : DbContext 
      { 
          public YourContext() 
          { 
              this.Configuration.AutoDetectChangesEnabled = false; 
          }  
      }  
      

      那么你不能这样做ChangeTracker.Entries&lt;IAuditable&gt;().Where(x =&gt; x.State == EntityState.Modified).ToList()

      如果您需要禁用代理创建,那么您必须在上下文的构造函数中执行此操作,如下所示。

      public class YourContext : DbContext 
      { 
          public YourContext() 
          { 
              this.Configuration.ProxyCreationEnabled = false; 
          }  
      
          public DbSet<Blog> Blogs { get; set; } 
          public DbSet<Post> Posts { get; set; } 
      }
      

      代理创建机制用于支持延迟加载关系。 EF 不会为代理无需执行任何操作的类型创建代理。换句话说,如果你的 POCO 类上没有 virtual 属性,那么无论你是否禁用它都没有影响。

      如果您要序列化实体,请考虑关闭代理和延迟加载,因为反序列化代理可能会很棘手。

      您可以在这里阅读更多信息:Entity Framework Working with Proxies

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-06-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多