edit
This commit is contained in:
@@ -259,7 +259,7 @@ SELECT @@ROWCOUNT;";
|
||||
}
|
||||
}
|
||||
|
||||
public void DeleteSpnmtpItem(int id)
|
||||
public SpnmtpDeleteResult DeleteSpnmtpItem(int id)
|
||||
{
|
||||
if (id <= 0)
|
||||
{
|
||||
@@ -275,21 +275,42 @@ SELECT @@ROWCOUNT;";
|
||||
try
|
||||
{
|
||||
using (var connection = CreateConnection())
|
||||
using (var command = new SqlCommand(sql, connection))
|
||||
{
|
||||
connection.Open();
|
||||
command.CommandTimeout = 60;
|
||||
command.Parameters.Add("@Id", SqlDbType.Int).Value = id;
|
||||
|
||||
if (Convert.ToInt32(command.ExecuteScalar()) == 0)
|
||||
var blockers = LoadSpnmtpDeleteBlockers(connection, id);
|
||||
if (blockers.Count > 0)
|
||||
{
|
||||
throw new InvalidOperationException("Запись SPNMTP для удаления не найдена.");
|
||||
return new SpnmtpDeleteResult
|
||||
{
|
||||
IsDeleted = false,
|
||||
WarningMessage = CreateSpnmtpDeleteBlockedMessage(blockers)
|
||||
};
|
||||
}
|
||||
|
||||
using (var command = new SqlCommand(sql, connection))
|
||||
{
|
||||
command.CommandTimeout = 60;
|
||||
command.Parameters.Add("@Id", SqlDbType.Int).Value = id;
|
||||
|
||||
if (Convert.ToInt32(command.ExecuteScalar()) == 0)
|
||||
{
|
||||
throw new InvalidOperationException("Запись SPNMTP для удаления не найдена.");
|
||||
}
|
||||
}
|
||||
|
||||
return new SpnmtpDeleteResult
|
||||
{
|
||||
IsDeleted = true
|
||||
};
|
||||
}
|
||||
}
|
||||
catch (SqlException ex) when (ex.Number == 547)
|
||||
{
|
||||
throw new InvalidOperationException("Запись справочника используется в связанных данных и не может быть удалена.", ex);
|
||||
return new SpnmtpDeleteResult
|
||||
{
|
||||
IsDeleted = false,
|
||||
WarningMessage = CreateSpnmtpDeleteBlockedMessage(ex)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2337,6 +2358,69 @@ WHERE NMTP = @Name
|
||||
innerException);
|
||||
}
|
||||
|
||||
private static List<DeleteBlockerInfo> LoadSpnmtpDeleteBlockers(SqlConnection connection, int id)
|
||||
{
|
||||
const string sql = @"
|
||||
SELECT blocker.TableName, blocker.LinkCount
|
||||
FROM
|
||||
(
|
||||
SELECT N'TIPS' AS TableName, COUNT(*) AS LinkCount
|
||||
FROM dbo.TIPS
|
||||
WHERE IDSPNMTP = @Id
|
||||
) blocker
|
||||
WHERE blocker.LinkCount > 0
|
||||
ORDER BY blocker.TableName;";
|
||||
|
||||
var blockers = new List<DeleteBlockerInfo>();
|
||||
|
||||
using (var command = new SqlCommand(sql, connection))
|
||||
{
|
||||
command.CommandTimeout = 60;
|
||||
command.Parameters.Add("@Id", SqlDbType.Int).Value = id;
|
||||
|
||||
using (var reader = command.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
blockers.Add(new DeleteBlockerInfo
|
||||
{
|
||||
TableName = GetString(reader, "TableName"),
|
||||
RowCount = GetInt32(reader, "LinkCount")
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return blockers;
|
||||
}
|
||||
|
||||
private static string CreateSpnmtpDeleteBlockedMessage(IEnumerable<DeleteBlockerInfo> blockers)
|
||||
{
|
||||
var blockerList = blockers == null
|
||||
? new List<DeleteBlockerInfo>()
|
||||
: blockers.Where(delegate(DeleteBlockerInfo blocker) { return blocker != null; }).ToList();
|
||||
var details = blockerList.Count == 0
|
||||
? "TIPS"
|
||||
: string.Join(", ", blockerList.Select(delegate(DeleteBlockerInfo blocker)
|
||||
{
|
||||
return string.Format("{0}: {1}", blocker.TableName, blocker.RowCount);
|
||||
}));
|
||||
|
||||
return string.Format(
|
||||
"Запись SPNMTP не может быть удалена, потому что на неё есть ссылки в таблицах: {0}. Подтверждённое ограничение БД: FK_TIPS_SPNMTP (dbo.TIPS.IDSPNMTP -> dbo.SPNMTP.IDSPNMTP).",
|
||||
details);
|
||||
}
|
||||
|
||||
private static string CreateSpnmtpDeleteBlockedMessage(SqlException ex)
|
||||
{
|
||||
if (ex != null && ex.Message.IndexOf("FK_TIPS_SPNMTP", StringComparison.OrdinalIgnoreCase) >= 0)
|
||||
{
|
||||
return "Запись SPNMTP не может быть удалена, потому что на неё есть ссылки в таблице TIPS. Ограничение БД: FK_TIPS_SPNMTP (dbo.TIPS.IDSPNMTP -> dbo.SPNMTP.IDSPNMTP).";
|
||||
}
|
||||
|
||||
return "Запись SPNMTP не может быть удалена из-за ограничения ссылочной целостности в БД.";
|
||||
}
|
||||
|
||||
private static bool IsSpnmtpDuplicateNameViolation(SqlException ex)
|
||||
{
|
||||
return ex != null
|
||||
|
||||
@@ -353,6 +353,13 @@ namespace XLAB
|
||||
public string SpecialName { get; set; }
|
||||
}
|
||||
|
||||
internal sealed class SpnmtpDeleteResult
|
||||
{
|
||||
public bool IsDeleted { get; set; }
|
||||
|
||||
public string WarningMessage { get; set; }
|
||||
}
|
||||
|
||||
internal static class SpnmtpDirectoryRules
|
||||
{
|
||||
public const int NameMaxLength = 150;
|
||||
|
||||
@@ -132,7 +132,13 @@ namespace XLAB
|
||||
|
||||
RunMutationOperation(async delegate
|
||||
{
|
||||
await Task.Run(delegate { _service.DeleteSpnmtpItem(selectedItem.Id); });
|
||||
var deleteResult = await Task.Run(delegate { return _service.DeleteSpnmtpItem(selectedItem.Id); });
|
||||
if (!deleteResult.IsDeleted)
|
||||
{
|
||||
_dialogService.ShowWarning(deleteResult.WarningMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
await RefreshCoreAsync(null);
|
||||
_dialogService.ShowInfo("Запись справочника удалена.");
|
||||
});
|
||||
@@ -255,12 +261,28 @@ namespace XLAB
|
||||
|
||||
private async void RunBusyOperation(Func<Task> operation)
|
||||
{
|
||||
await ExecuteBusyOperationAsync(operation);
|
||||
try
|
||||
{
|
||||
await ExecuteBusyOperationAsync(operation);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
IsBusy = false;
|
||||
_dialogService.ShowError(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private async void RunMutationOperation(Func<Task> operation)
|
||||
{
|
||||
await ExecuteMutationOperationAsync(operation);
|
||||
try
|
||||
{
|
||||
await ExecuteMutationOperationAsync(operation);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
IsBusy = false;
|
||||
_dialogService.ShowError(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateStatus()
|
||||
|
||||
Reference in New Issue
Block a user