C# 导航属性和查找实体

C# 导航属性和查找实体,c#,entity-framework,C#,Entity Framework,我有一个代码优先实体,如下所示: public class Account { public Guid Id { get; set; } public int AccountTypeId { get; set; } [ForeignKey("AccountTypeId")] public virtual AccountType AccountType { get; set; } } AccountType是一个只读的查找表。我们永远不想修改它 当我查询帐户时

我有一个代码优先实体,如下所示:

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有关系的交易实体中获取大约100个交易并尝试修改其中一个时,EF会尝试将所有数百个帐户记录保存在数据库中,因为它认为它们的AccountType已更改!为什么会发生这种情况?我们如何预防它

如果我们将AccountType与[NotMapped]取消映射,则不会发生这种情况。但这样就不能再在任何LINQ to实体查询中参与此属性

有没有什么方法可以使用离线C集合中的查找表,并且仍然能够在LINQ to实体中使用它们而不会出现这些问题?枚举类型太有限,无法扩展。正确的方法是什么


谢谢

您可以通过重写来取消所有修改的AccountType


应用程序中所有已修改的AccountType都不会更新到数据库。

否,它不会尝试更新AccountType实体。它认为所有帐户实体的AccountType属性都已更改,并尝试更新所有这些帐户。很抱歉混淆了命名。@orad,然后将ChangeTracker的用法更改为ChangeTracker.Entries。好的,这将取消对所有帐户的跟踪,即使它们确实已更改。我需要找到一种避免错误更新的方法。
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();
    }
}