如何在流利的迁移器中捕获特定的 SQL 异常?

How to catch specific SQL exception in fluent migrator?

我正在编写应该删除重复行的迁移,但是可能会使用一些 ID,因此对于这种情况,记录应设置为非活动状态。我已经编写了应该工作的迁移 :) 但我想知道是否有可能捕获特定的 ForeignKeyException?只有在删除行时发生外键错误时,我才想尝试将 active 设置为 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");
    }
}

你可以这样处理它:

        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
        }