根据我的阅读,设置ProxyCreationEnabled = false
会阻止更改跟踪和延迟加载。但是,我不清楚跟踪所涵盖的变化。
如果我禁用它并从数据库中获取实体,请对其进行更改并提交,然后保存这些更改。我还能够从ChangeTracker获得修改后的条目:
ChangeTracker.Entries<IAuditable>().Where(x => x.State == EntityState.Modified).ToList()
当我禁用代理创建时,这是否可行?我想禁用它,但我希望清楚我禁用的内容。
答案 0 :(得分:10)
我可以确认在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()
您的示例代码。
答案 1 :(得分:7)
更改跟踪和代理创建是两种不同的方案。如果您需要禁用更改跟踪,则必须执行此操作,如下所示。
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
属性,那么你是否禁用了它就没有效果。
如果您要序列化您的实体,请考虑关闭代理和延迟加载,因为反序列化代理可能会很棘手。
您可以在此处详细了解:Entity Framework Working with Proxies