如何在流利的迁移器中捕获特定的 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
}
我正在编写应该删除重复行的迁移,但是可能会使用一些 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
}