Как отловить конкретное исключение SQL в беглом миграторе? - PullRequest
0 голосов
/ 31 мая 2019

Я пишу миграцию, которая должна удалить повторяющиеся строки, однако возможно, что некоторые идентификаторы будут использоваться, поэтому для этого сценария записи должны быть установлены в неактивное состояние. Я написал миграцию, которая должна работать :) Но я хотел бы знать, можно ли поймать конкретную ForeignKeyException? Я хочу попробовать установить активное значение 0, только если при удалении строк возникает ошибка внешнего ключа. База данных на сервере sql.

Миграция

[Migration(201905311022)]
public class _201905311022_RemoveDuplicatesFromCarrierLookUp : Migration
{
    private const string row_number = "row_number";
    private const string CTE = "CTE";
    private const string LookUp_Carrier = "LookUp_Carrier";
    private const string CarrierId = "CarrierId";
    private const string Carrier = "Carrier";
    private readonly string WithCte = $@"
WITH CTE AS
(SELECT {Carrier}, {CarrierId}, ROW_NUMBER() OVER(PARTITION BY {Carrier} 
ORDER BY {CarrierId}) as {row_number} FROM {LookUp_Carrier})";

    public override void Up()
    {
        try
        {
            RemoveRecordsWithSameName();
        }
        catch(Exception foreignKeyConstrain)
        {
            MakeRecordsWithSameNameInActive();
        }
    }

    private void MakeRecordsWithSameNameInActive()
    {
        Execute.Sql($@"{WithCte}
UPDATE {LookUp_Carrier}
SET Active = 0
WHERE {CarrierId} in (SELECT {CarrierId} FROM {CTE} WHERE {row_number} <> 1)");
    }

    private void RemoveRecordsWithSameName()
    {
        Execute.Sql($@"{WithCte}
  DELETE FROM {LookUp_Carrier} WHERE {CarrierId} IN (SELECT {CarrierId} FROM {CTE} WHERE {row_number} <> 1)");
    }

    public override void Down()
    {
        Console.WriteLine("Rollback for data manipulation wasn't implemented");
    }
}

1 Ответ

1 голос
/ 31 мая 2019

Вы можете обработать это примерно так:

        try
        {
            RemoveRecordsWithSameName();
        }
        catch (SqlException ex)
        {
             if (ex.Errors.Count > 0) // Assume the interesting stuff is in the first error
            {
             switch (ex.Errors[0].Number)
            {
            case 547: // Foreign Key violation but you have to check number
                MakeRecordsWithSameNameInActive();
                break;               
            default:
                throw new DataAccessException(ex);
            }
            }

        }          
        catch(Exception ex)
        {
          //process regular exception
        }
...