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)
|
if (id <= 0)
|
||||||
{
|
{
|
||||||
@@ -275,21 +275,42 @@ SELECT @@ROWCOUNT;";
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (var connection = CreateConnection())
|
using (var connection = CreateConnection())
|
||||||
using (var command = new SqlCommand(sql, connection))
|
|
||||||
{
|
{
|
||||||
connection.Open();
|
connection.Open();
|
||||||
command.CommandTimeout = 60;
|
var blockers = LoadSpnmtpDeleteBlockers(connection, id);
|
||||||
command.Parameters.Add("@Id", SqlDbType.Int).Value = id;
|
if (blockers.Count > 0)
|
||||||
|
|
||||||
if (Convert.ToInt32(command.ExecuteScalar()) == 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)
|
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);
|
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)
|
private static bool IsSpnmtpDuplicateNameViolation(SqlException ex)
|
||||||
{
|
{
|
||||||
return ex != null
|
return ex != null
|
||||||
|
|||||||
@@ -353,6 +353,13 @@ namespace XLAB
|
|||||||
public string SpecialName { get; set; }
|
public string SpecialName { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal sealed class SpnmtpDeleteResult
|
||||||
|
{
|
||||||
|
public bool IsDeleted { get; set; }
|
||||||
|
|
||||||
|
public string WarningMessage { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
internal static class SpnmtpDirectoryRules
|
internal static class SpnmtpDirectoryRules
|
||||||
{
|
{
|
||||||
public const int NameMaxLength = 150;
|
public const int NameMaxLength = 150;
|
||||||
|
|||||||
@@ -132,7 +132,13 @@ namespace XLAB
|
|||||||
|
|
||||||
RunMutationOperation(async delegate
|
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);
|
await RefreshCoreAsync(null);
|
||||||
_dialogService.ShowInfo("Запись справочника удалена.");
|
_dialogService.ShowInfo("Запись справочника удалена.");
|
||||||
});
|
});
|
||||||
@@ -255,12 +261,28 @@ namespace XLAB
|
|||||||
|
|
||||||
private async void RunBusyOperation(Func<Task> operation)
|
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)
|
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()
|
private void UpdateStatus()
|
||||||
|
|||||||
Reference in New Issue
Block a user