是否可以在EventHandler中获取调用SaveChanges()方法的类?
那是因为我有一个名为Activity的实体,它可以让系统的某些部分改变它的状态,我需要记录它并保存在数据库中。在日志表中,我需要存储已更新或创建的实体的ID,从而导致活动状态发生变化。
我想我可以做到或尝试不可维护的解决方案。 不可维护的解决方案是在系统的每个部分添加一些代码来改变活动状态。
PS:我不能使用数据库触发器..
答案 0 :(得分:2)
我不认为尝试更新另一个表作为SaveChanges
的一部分是正确的方法,您可以将您的日志记录机制耦合到该特定上下文 - 如果您想要禁用日志记录或切换它,该怎么办?出来使用不同类型的日志记录?即本地文件。
如果更新成功,我会更新日志表以及实体本身,即
var entity = ...
// update entity
if (context.SaveChanges() != 0)
{
// update log table
}
答案 1 :(得分:2)
使用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之后在一个threadstatic变量中,然后将其清除
答案 2 :(得分:1)
从你的帖子中听起来你更感兴趣的是哪些实体正在更新,而不是名为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();
}