重写“保存更改”并删除 EF 关系时为空
本文关键字:保存更改 关系 EF 删除 重写 | 更新日期: 2023-09-27 17:56:08
在我的多对一关系中,我正在尝试删除其中一个子对象,并在我覆盖的 SaveChanges 中保留审计跟踪。
该文件。Entity.Product 在执行 EntityState.Modified 或 EntityState.Add 时不为 null,但在执行 .删除的 EF 似乎甚至在 base 之前就积极地从实体中删除关系。savechanges() 被调用。
在我调用 .删除文件(子)?
var files = from e in ChangeTracker.Entries<SavedFile>()
where e.State != EntityState.Unchanged
select e;
if (file.State == EntityState.Deleted)
{
var text = "File Deleted: " + file.Entity.FriendlyFileName;
// file.Entity.Product is null
var updatedProduct = new Update { Product = file.Entity.Product, UpdateDateTime = DateTime.Now, UpdateText = text, User = HttpContext.Current.Request.LogonUserIdentity.Name };
Updates.Add(updatedProduct);
}
就像你在ChangeTracker
的条目中找到文件一样,你可以找到它的产品,假设File
与Product
有外键关联,即除了Product
导航属性之外,它还具有ProductID
属性:
if (file.State == EntityState.Deleted)
{
var text = "File Deleted: " + file.Entity.FriendlyFileName;
var productEntry = ChangeTracker.Entries<Product>()
.FirstOrDefault(p => p.Entity.ID == file.ProductID);
if (productEntry != null)
{
var updatedProduct = new Update { Product = productEntry.Entity, UpdateDateTime = DateTime.Now, UpdateText = text, User = HttpContext.Current.Request.LogonUserIdentity.Name };
Updates.Add(updatedProduct);
}
}
预期行为是,每当从本地缓存查询实体时,EF 都不会显示已删除的实体(例如 DbSet.Local
)。因此,它还必须断开关联,以防止这些实体出现在导航属性中。如果删除文件,EF 不会以 context.Files.Local
显示该文件,但它也不会在导航属性(如 product.Files
)中可见(关联的另一端也不会file.Product
)。
我认为删除后无法访问关系船
但是,为什么不使用软删除,在我看来这是最佳实践,如果被错误删除,您可以随时返回已删除的记录(通过标记 IsDelete = false,由具有权限的管理员)
希望这对你有帮助
如果只需要 Product
属性使用它,则可以在其定义上使用一些自定义逻辑来捕获它:
class File {
...
private Product product;
private Product lastProduct;
public Product Product {
get { return product; }
set {
if (product == value) return;
lastProduct = Product;
product = value;
}
}
[NotMapped]
public Product LastProduct {
get { return lastProduct; }
}
...
}
Gert Arnold 提供的答案应该有效 - 但不确定检查是否有意义 FirstOrDefault(p => p.State != EntityState.Unchanged因为相关实体可能仍处于"未更改"状态。
如果没有任何效果,请尝试在重写的 SaveChanges 方法中重新加载实体。
this.Entry((file.Entity as <<Your Entity Type>>)).Reload();
//do your operation/audit log
//then reset the Entity State to Deleted
this.Entry((file.Entity)).State = EntityState.Deleted;
编辑:或仅显式加载所需的相关实体
this.Entry(file.Entity as <Type>).Reference(e=> e.Product).Load();
这最终会在重新加载时造成额外的数据库命中。
编辑:另一个选项,如果没有找到其他好的选项
如何在此方案中执行原始 SQL 插入查询以填充审核表?