禁用实体框架代理创建

本文关键字:代理 创建 框架 实体 | 更新日期: 2023-09-27 18:17:57

据我所知,设置ProxyCreationEnabled = false将防止更改跟踪和延迟加载。但是,我不清楚变更跟踪包括哪些内容。

如果我禁用它并从数据库中获取一个实体,对它进行更改并提交,那么这些更改将被保存。我还能够从ChangeTracker获得修改过的条目:

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

当我禁用代理创建时,这是否可能?我想禁用它,但我想明确我要禁用的是什么

禁用实体框架代理创建

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

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

那么你不能这样做,ChangeTracker.Entries<IAuditable>().Where(x => 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属性,那么无论你是否禁用它都没有效果。

如果你正在序列化你的实体,那么考虑关闭代理和延迟加载,因为反序列化代理可能会很棘手。

使用代理的实体框架

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

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

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()