C# EF-调用SaveChanges()的类
是否可以在EventHandler中获取调用SaveChanges方法的类 这是因为我有一个名为Activity的实体,它可以让系统的某些部分更改它的状态,我需要记录它并保存在数据库中。在日志表中,我需要存储更新或创建的实体的ID,从而导致活动状态更改 我想我可以这样做,也可以尝试无法维护的解决方案。 不可维护的解决方案是向系统中更改活动状态的每个部分添加一些代码C# EF-调用SaveChanges()的类,c#,asp.net,C#,Asp.net,是否可以在EventHandler中获取调用SaveChanges方法的类 这是因为我有一个名为Activity的实体,它可以让系统的某些部分更改它的状态,我需要记录它并保存在数据库中。在日志表中,我需要存储更新或创建的实体的ID,从而导致活动状态更改 我想我可以这样做,也可以尝试无法维护的解决方案。 不可维护的解决方案是向系统中更改活动状态的每个部分添加一些代码 PS:我不能使用数据库触发器。我不认为尝试更新另一个表作为SaveChanges的一部分是正确的方法,您可能会将日志机制与特定的上下
PS:我不能使用数据库触发器。我不认为尝试更新另一个表作为SaveChanges的一部分是正确的方法,您可能会将日志机制与特定的上下文相耦合-如果您想禁用日志记录或将其切换为使用其他类型的日志记录,该怎么办?i、 e.本地文件 如果更新成功,我将更新日志表以及实体本身,即
var entity = ...
// update entity
if (context.SaveChanges() != 0)
{
// update log table
}
我不认为尝试更新另一个表作为SaveChanges的一部分是正确的方法,您应该将日志机制与特定的上下文相耦合——如果您想禁用日志记录或将其切换为使用不同类型的日志记录,该怎么办?i、 e.本地文件 如果更新成功,我将更新日志表以及实体本身,即
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之前将调用者存储在threadstatic变量中,然后在调用SaveChanges之后将其清除这是可能的,但我建议不要使用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变量中,然后从您的帖子中清除调用者。听起来您更感兴趣的是更新哪些实体,而不是调用哪个方法保存更改 如果是这种情况,您可以检查挂起的更改,并查看添加、修改或删除了哪些实体(如果您关心这些信息并根据这些信息进行日志记录) 您可以这样做:
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();
}
从你的帖子中,听起来你更感兴趣的是哪个实体正在更新,而不是哪个方法叫做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();
}
EventHandler通常采用Object sender的第一个参数,该参数应该是调用者?@Belogix sender对象通常是对引发事件的对象的引用,而不是调用事件的对象的引用。@Belogix,发送者是ObjectContext,因为我将事件处理程序附加到该方法,在调用SaveChanges之后,在数据库中更新数据之前调用。EventHandler通常采用对象sender的第一个参数,该参数应该是调用者?@Belogix发送者对象通常是对引发事件的对象的引用,而不是对调用它的对象的引用。@Belogix,发送方是ObjectContext,因为我将事件处理程序附加到该方法,该方法在调用SaveChanges之后、在数据库中更新数据之前调用。如果记录的信息需要准确,这也意味着该程序需要在不进行优化的情况下编译,不是吗?很好的一点-但是只要调用方法不是微不足道的,那么它就不应该是内联的如果记录的信息需要准确,这也意味着程序需要在没有优化的情况下编译,这不是吗?很好的一点-但只要调用方法不是微不足道的,那么它就不应该是内联的,这就是我认为最好的解决方案。我可以检查活动实体是否具有已修改状态,然后检查其他也具有此已修改状态的实体,然后保存它。我会尝试一下,然后给你反馈。这是我认为最好的解决方案。我可以检查活动实体是否具有修改状态,然后检查其他也具有此修改状态的实体 d状态,然后保存它。我会尝试一下,然后给你反馈。