禁用实体框架代理创建

Tom*_*Tom 10 c# entity-framework

根据我的阅读,设置ProxyCreationEnabled = false将阻止更改跟踪和延迟加载.但是,我不清楚跟踪的变化.

如果我禁用它并从数据库中获取实体,对其进行更改并提交,则会保存这些更改.我还可以从ChangeTracker获得修改后的条目:

ChangeTracker.Entries<IAuditable>().Where(x => x.State == EntityState.Modified).ToList()
Run Code Online (Sandbox Code Playgroud)

我禁用代理创建时是否可以这样做?我想禁用它,但我想明确我禁用的内容.

Rud*_*ser 11

我可以确认ProxyCreationEnabled在EF中设置为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; }
    }
}
Run Code Online (Sandbox Code Playgroud)

禁用代理生成应该影响的唯一因素是当您将virtual导航属性用于其他模型时,EF的延迟加载功能.Change Tracker是独立的,可以从底层ObjectContext本身开始工作.

有关更改跟踪的完整答案,可能值得注意的是,这AutoDetectChangesEnabled似乎是唯一会直接影响更改跟踪功能的设置,要求您在DetectChanges()需要使用示例代码时进行调用.


Sam*_*ath 7

更改跟踪和代理创建是两种不同的方案.如果您需要禁用更改跟踪,则必须执行此操作,如下所示.

public class YourContext : DbContext 
{ 
    public YourContext() 
    { 
        this.Configuration.AutoDetectChangesEnabled = false; 
    }  
}  
Run Code Online (Sandbox Code Playgroud)

那你不能这样做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; } 
}
Run Code Online (Sandbox Code Playgroud)

代理创建机制用于支持延迟加载关系.EF不会为代理没有任何内容的类型创建代理.换句话说,如果您virtual的POCO类没有属性,则无论是否禁用它都没有效果.

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

您可以在此处阅读更多相关信息:实体框架使用代理