簡體   English   中英

在Entity Framework中運行db.SaveChanges時是否可以知道哪個函數引發了錯誤?

[英]Is it possible to know which function threw the error when running db.SaveChanges in Entity Framework?

我們希望將錯誤存儲在數據庫表中,以便在項目投入生產時可以查找出哪里出錯了。 我們想捕獲運行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並捕獲它,然后將其與存在錯誤的函數以這種方式保存,但是為了簡化起見,我希望能夠將它放在一個地方。

您需要來電者信息

如果您想要調用您的方法的名稱,聲明此方法的文件和行號,請​​執行以下操作:

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!
}

您必須為每個可選參數指定一個明確的默認值。 您不能將“來電者信息”屬性應用於未指定為可選參數的參數。

呼叫者信息屬性不會將參數設為可選。 相反,它們會影響省略參數時傳遞的默認值。

在編譯時,呼叫者信息值將作為文字發送到中間語言(IL)中。 與用於例外的StackTrace屬性的結果不同,結果不受混淆的影響。

在極少數情況下,您不希望使用默認值,則可以顯式命名它們:

void ChangeCity(string city)
{
    ...
    DbContext.SaveChanges($"{nameof(ChangeCity)} where city = {city}");
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM