调用SaveChanges()的类

本文关键字:的类 SaveChanges 调用 | 更新日期: 2023-09-27 18:13:47

是否有可能获得在EventHandler中调用SaveChanges()方法的类?

那是因为我有一个名为Activity的实体,它可以被系统的某些部分改变状态,我需要记录它并保存在数据库中。在日志表中,我需要存储被更新或创建的实体的id,从而导致活动状态更改。

我想我要么这样做,要么尝试不可维护的解决方案。不可维护的解决方案是向系统的每个部分添加一些代码来更改活动状态。

PS:我不能使用数据库触发器…

调用SaveChanges()的类

我不认为尝试更新另一个表作为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();
}