c# - Entity Framework Core - 如何使用通用方法在 SaveChanges 期间动态记录相关实体属性更改?
问题描述
我最近正在围绕 Audit ChangeLog 部分学习 EF Core,在那里我发现大多数资源仅通过使用反射将日志作为实体的直接属性进行跟踪,假设我有两个相关实体:
public Class Order
{
public int OrderId {get; set;}
public int OrderName {get; set;}
public virtual Collection<OrderDetail> OrderDetails { get; set; } = new Collection<OrderDetail>();
}
public Class OrderDetail
{
public int OrderDetailId {get; set;}
public int OrderDetailName {get; set;}
public int OrderDetailQuantity {get; set;}
public int? OrderID { get; set; }
public virtual Order OrderFk { get; set; }
}
然后我的 TrackChange 就像:
protected virtual IEnumerable<ChangeLog> TrackChange()
{
foreach (var entry in DbContext.ChangeTracker.Entries())
{
var entityType = entry.Entity.GetType();
foreach (var property in entityType.GetTypeInfo().DeclaredProperties)
{
var originalValue = entry.Property(property.Name).OriginalValue;
var currentValue = entry.Property(property.Name).CurrentValue;
//Log if originalValue != currentValue
}
}
}
因此,如果我有一个包含 3 个 OrderDetails 的订单,那么我通过更新 OrderDetailQuantity并保存为 Order 来修改Order Name和其中一个 OrderDetail ,TrackChange 将捕获我的 OrderName 更改,因为这是 Order 的一个属性,但是当“entityType 中的属性” .GetTypeInfo().DeclaredProperties" 变为 "OrderDetails",它不够聪明,无法检测到这是“Order”的集合或相关实体,然后在尝试获取 originalValue 时出现异常:
'The property 'OrderDetails' on entity type 'Order' is being accessed using the 'Property' method, but is defined in the model as a navigation property. Use either the 'Reference' or 'Collection' method to access navigation properties.'
我知道我可能可以使用 entry.Collection(property.Name) 进入“OrderDetail”集合,但问题是:我怎么知道当前属性是像 Int/String/Datetime 这样的值类型,而它也可以是相关实体还是当前条目的集合?
关于 TrackChange 及以下的其他想法是我的伪代码想法:
function TrackChange(Entity)
//Track Base Entity Change
...
//Track Child Entity Change if there is any
if (Entity.HasChildNode)
{
foreach(ChildEntity of Entity.ChildEntities)
TrackChange(ChildEntity);
}
...
}
因为我的 TrackChange 是通用的,所以我希望有一种方法可以使用 C# 反射来实现上述想法。
解决方案
推荐阅读
- c# - 无法通过 NuGet 管理器安装/更新任何包
- python - 合并两个 for 循环以将 1 个值映射到其他 1 对 1 映射
- python-3.x - AttributeError:在主窗口(kivy)上运行弹出功能时,“MainWindow”对象没有属性“btn”错误
- templates - 如何根据实例化特征有条件地编码模板函数/类?
- angular - 带有常春藤的 Angular 8 无法构建
- php - 仓位分配未分配正确的金额
- xamarin - Xamarin 表单的 Keyup 事件处理程序?
- java - 图数据上的 MapReduce - reducer 返回不正确的附加数据
- android - FFmpeg忽略开始时间修剪音频文件android
- python - 来自多个数据帧的多个直方图在熊猫中合二为一