是否可以在 EventHandler 中获取调用 SaveChanges() 方法的类?
那是因为我有一个名为 Activity 的实体,它的状态可以被系统的某些部分更改,我需要记录它并保存在数据库中。在日志表中,我需要存储已更新或创建的实体的 ID,从而导致活动状态发生变化。
我想我可以做到这一点,或者尝试不可维护的解决方案。不可维护的解决方案是向系统的每个部分添加一些代码来更改活动状态。
PS:我不能使用数据库触发器..
我不认为尝试更新另一个表作为SaveChanges
这里的正确方法,您会将日志记录机制耦合到该特定上下文 - 如果您想禁用日志记录或将其切换为使用不同类型的日志记录怎么办? 即本地文件。
如果更新成功,我将更新日志表以及实体本身,即
var entity = ...
// update entity
if (context.SaveChanges() != 0)
{
// update log table
}
使用 StackTrace 是可能的(但我建议不要这样做),例如:
public class Test
{
public event EventHandler AnEvent;
public Test()
{
AnEvent += WhoDoneIt;
}
public void Trigger()
{
if (AnEvent != null)
AnEvent(this, EventArgs.Empty);
}
public void WhoDoneIt(object sender, EventArgs eventArgs)
{
var stack = new StackTrace();
for (var i = 0; i < stack.FrameCount; i++)
{
var frame = stack.GetFrame(i);
var method = frame.GetMethod();
Console.WriteLine("{0}:{1}.{2}", i, method.DeclaringType.FullName, method.Name);
}
}
}
public class Program
{
static void Main(string[] args)
{
var test = new Test();
test.Trigger();
Console.ReadLine();
}
}
如果您查看程序的输出,您可以找出您想要查看的堆栈帧,并根据该帧的方法分析调用者。
但是,这可能会产生严重的性能影响 - 堆栈跟踪是一个非常昂贵的创建对象,所以我真的建议更改代码以以不同的方式跟踪调用者 - 一个想法可能是将调用者存储在线程静态中调用 SaveChanges 之前的变量,然后将其清除
从您的帖子看来,您更感兴趣的是哪些实体正在更新,而不是哪种方法称为 SaveChanges。
如果是这种情况,您可以检查挂起的更改并查看添加或修改了哪些实体(如果您关心,也可以删除),并根据该信息进行日志记录。
你会这样做:
public override int SaveChanges()
{
if (changeSet != null)
foreach (var dbEntityEntry in ChangeTracker.Entries())
{
switch (dbEntityEntry.State)
{
case EntityState.Added:
// log your data
break;
case EntityState.Modified:
// log your data
break;
}
}
return base.SaveChanges();
}