导航属性和查找实体
本文关键字:实体 查找 属性 导航 | 更新日期: 2023-09-27 18:18:24
我有一个代码优先的实体,看起来像这样:
public class Account
{
public Guid Id { get; set; }
public int AccountTypeId { get; set; }
[ForeignKey("AccountTypeId")]
public virtual AccountType AccountType { get; set; }
}
AccountType
是一个被视为只读的查找表。我们永远不会想要修改它。
当我查询一个帐户时,AccountTypeId
和AccountType
都用数据库中的正确值填充。但是,当更新这两个属性中的任何一个时,另一个属性不会得到更新,直到我们调用SaveChanges()
访问服务器。我们不想在早期点击服务器来保存东西,并且对于实体的一些单元测试,我们不能依赖于对dbContext.SaveChanges()
方法的调用,所以我们覆盖了导航属性以从离线集合中获取其值,如下所示:
public class Account
{
public Guid Id { get; set; }
public int AccountTypeId { get; set; }
[ForeignKey("AccountTypeId")]
public virtual AccountType AccountType
{
get
{
return AccountTypeCollection.GetById(this.FormatTypeId);
}
set
{
this.AccountTypeId = (value ?? AccountTypeCollection.None).Id;
}
}
}
这样,我们仍然可以在LINQ查询中使用AccountType
导航属性,并确保它始终与AccountTypeId
同步。然而,我们发现的问题是,在某些情况下,我们会受到很大的性能影响。例如,当我们从与Account
有关系的Transaction
实体获得数百个交易并试图修改一个时,EF试图将所有数百个帐户记录保存在数据库中,因为它认为他们的AccountType
发生了变化!为什么会发生这种情况?我们如何预防它?
如果我们取消AccountType
与[NotMapped]的映射,那么这将不会发生。但是不能再在任何LINQ-to-Entity查询中参与此属性。
我们是否可以使用离线c#集合中的查找表,并且仍然能够在LINQ-to-Entities中使用它们而不会出现这些问题?枚举类型的限制太大,不能扩展。正确的做法是什么?
谢谢!
您可以通过覆盖 SaveChanges
来取消所有修改过的AccountType
。
public class YourContext : DbContext
{
// dbsets
public override int SaveChanges()
{
var entries = ChangeTracker.Entries<AccountType>()
.Where(at => at.State == EntityState.Modified);
foreach (var entry in entries)
{
entry.State = EntityState.Unchanged;
}
return base.SaveChanges();
}
}
应用程序中所有修改的AccountType
将不会更新到数据库