我们希望将错误存储在数据库表中,以便在项目投入生产时找到出错的地方。我们希望捕获运行db.SaveChanges()
时发生的错误。我们无法在生产中运行调试器,因此这是我们能够保存错误的答案。
到目前为止,我有这个:
public override int SaveChanges()
{
try
{
return base.SaveChanges();
}
catch (DbEntityValidationException e)
{
var errorMessages = e.EntityValidationErrors
.SelectMany(x => x.ValidationErrors)
.Select(x => x.ErrorMessage);
// Join the list to a single string.
var fullErrorMessage = string.Join("; ", errorMessages);
// Combine the original exception message with the new one.
var exceptionMessage = string.Concat(e.Message, " The validation errors are: ", fullErrorMessage);
// Throw a new DbEntityValidationException with the improved exception message.
throw new DbEntityValidationException(exceptionMessage, e.EntityValidationErrors);
}
catch (DbUpdateException ex)
{
Exception realerror = ex;
while (realerror.InnerException != null)
realerror = realerror.InnerException;
Console.WriteLine(realerror.ToString());
throw ex;
}
}
我正在尝试这样的事情,以便在SaveChanges()
运行时捕获错误,就像它在一个地方一样。有没有办法知道哪个函数称为SaveChanges()
,所以我可以将其保存在数据库中,以便我们可以看到它失败的位置或至少它被调用的行号?
我知道我可以为每个函数添加一个try-catch
并捕获它并使用它有错误的函数以这种方式保存它,但我希望能够将它放在一个位置简单。
答案 0 :(得分:1)
如果您想要调用方法的方法名称,声明此方法的文件和行号,请执行以下操作:
public void SaveChanges(string message,
[System.Runtime.CompilerServices.CallerMemberName] string callerMethod = "",
[System.Runtime.CompilerServices.CallerFilePath] string sourceFile = "",
[System.Runtime.CompilerServices.CallerLineNumber] int lineNumber = 0)
{
try
{
db.SaveChanges();
}
catch (...)
{
// here you can use callerMethod, sourceFile, lineNumber
// as string in your diagnostic message
}
}
用法:
using (var dbContext = new MyDbContext(...))
{
...
dbContext.SaveChanges(); // all parameters are optional!
}
您必须为每个可选参数指定显式默认值。您不能将Caller Info属性应用于未指定为可选参数。
“来电者信息”属性不会使参数成为可选参数。相反,它们会影响省略参数时传入的默认值。
在编译时,调用者信息值作为文字发送到中间语言(IL)。与异常的StackTrace属性的结果不同,结果不受混淆的影响。
在极少数情况下,您不需要默认值,您可以明确地命名它们:
void ChangeCity(string city)
{
...
DbContext.SaveChanges($"{nameof(ChangeCity)} where city = {city}");
}