【问题标题】:Entity Framework not all detecting changes on model实体框架并非全部检测模型上的更改
【发布时间】:2019-06-11 17:04:40
【问题描述】:

背景

我在重写的 SaveChanges 方法中有代码,该方法查找修改的或新的对象并为该对象创建哈希,但在这里我很难发现某个对象已更改。

代码

我已经设法将问题(尽管这可能只是正确的行为)提炼到这些行。

相关方法中的代码:

db.SaveChanges(); //for sake of easy example, ensure no other changes need to be saved
Models.File file1 = db.ImportFiles.Find(FileId);
file1.FileData = new FileData();
db.SaveChanges(); //run SaveChanges override which has custom code for hashing content

覆盖SaveChanges()中的主要代码块:

public override int SaveChanges(){
    var updates = ChangeTracker.Entries().ToList();
    var updateHashQueue = new List<DbEntityEntry>();
    foreach (DbEntityEntry entry in updates.Where(x => (x.State == EntityState.Added || x.State == EntityState.Modified)))
    {
        updateHashQueue.Add(entry); //only the FileData object shows here, never the File object
    }
    base.SaveChanges(); //Later hashing needs IDs to exist
    HashObjects(updateHashQueue); //takes relevant objects to create hashes (these objects have a "Hash" field)
    return base.SaveChanges();
}

说明

通过使其包含FileData 的实例来更改File 类型的模型,Entity Framework 的ChangeTracker.Entries() 包含FileData 对象和File 对象,但只有前者在@ 987654330@ 状态,而File 对象显示为EntityState.Unchanged

我在想这个问题的答案可能只是这正是它的工作方式,但我想知道是否有一种方法可以通用地选择这些模型,比如这个例子中的File,以这种方式改变了。

有什么想法吗?

【问题讨论】:

  • 您能否发布 SaveChanges() 的覆盖代码,因为这可能是问题所在。
  • 嗨,基兰,感谢您的建议。我在SaveChanges 的后半部分添加了一些额外的上下文,但我没有得到预期结果的主要部分似乎是ChangeTracker.Entries 中的Unchanged 状态File 对象。
  • File 对象永远不会改变,因为它在数据库中还不存在。
  • 但是当我运行db.ImportFiles.Find(FileId); 时,我正在提取一个现有文件,不是吗?
  • 抱歉,我把FileFileData 搞混了。

标签: c# entity-framework


【解决方案1】:

我很确定你只需要打电话:

db.SaveChanges();
Models.File file1 = db.ImportFiles.Find(FileId);
db.ImportFiles.Update(file1); //Added line
file1.FileData = new FileData();
db.SaveChanges(); 

这将告诉 entityframework 您希望 changetracker 开始跟踪实体状态。

【讨论】:

  • 我认为这个问题更多地与为什么 EF 更改跟踪器没有按照应有的方式自动获取状态更改有关。
  • hmm 我不认为默认情况下会跟踪导航属性,您可以按照描述通过调用 Update() 手动跟踪它们,或者(可能不确定)如果您使用来自 ef core 的包含语法.类似于: db.ImportFiles.Where(x => x.FileId == FileId) .Include(x => x.FileData) .FirstOrDefault();
  • EF 和 EF Core 默认都应该跟踪所有导航属性。 dotnetfiddle.net/3yiEUX
  • 我想我现在明白了这个问题......在你的小提琴中,客户实体也不会在 changetracker 中显示为已修改。那是因为您没有修改实体,而是添加了一个全新的实体。如果您希望它处于修改状态,则必须调用 Update。 (在您的小提琴中是一个小错误,它应该是 dump(list2) 并且您会看到它是一个全新的实体。
  • 没有人说应该跟踪子实体,@Geesh_SO 的问题是在设置导航属性时父记录没有被更新。同样在我的示例中,列表输出是相同的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-05
  • 1970-01-01
  • 2016-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多