禁用实体框架代理创建
本文关键字:代理 创建 框架 实体 | 更新日期: 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()
。