Можно ли узнать, какая функция вызвала ошибку при запуске db.SaveChanges в Entity Framework? - PullRequest
0 голосов
/ 06 июня 2018

Мы хотим сохранить наши ошибки в таблице базы данных, чтобы мы могли найти, где что-то пошло не так, когда наш проект находится в производстве.Мы хотим отлавливать ошибки, возникающие при запуске 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 к каждой функции, перехватить и сохранить ее таким образом, чтобы в ней была ошибка, но я надеялся, что смогу получить ее в одном местедля простоты.

1 Ответ

0 голосов
/ 07 июня 2018

Вам нужно Информация о вызывающем абоненте

Если вы хотите указать имя вызвавшего вас метода, файл, в котором объявлен этот метод, и номер строки, сделайте что-то вроде этого:

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}");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...