Refering to my previous topic: AutoCrud: how to combine softdelete and hard delete together in a single service?
Following the advice in mythz’s answers:
I decided to move my code from AutoPopulate to AutoApply, mentioned above, with custom behaviors, and it is working well.
However, I am struggling with my combined soft-delete/delete method. It is updating my audit attributes correctly, as required, for my soft-delete step. However, the hard delete is only hard deleting the database record sometimes, and I cannot determine the reasons.
From two approaches mentioned above, my preference was to use the PartialUpdate, as shown below:
// Perform a hard delete, after updating record with a soft delete
public DeleteResponse Delete(DeleteConfiguration request)
{
try
{
using var db = AutoQuery!.GetDb<Configuration>(base.Request);
// step 1: soft delete prerequiste
var response1 = (DeleteResponse)AutoQuery.PartialUpdate<Configuration>(request, base.Request);
if (response1.IsErrorResponse() || response1.Count == 0)
{
return response1;
}
else
{
// step 2: continue with requested hard delete
var response2 = (DeleteResponse)AutoQuery.Delete<Configuration>(request, base.Request);
return response2;
}
}
catch (Exception ex)
{
Log!.Error("Exception opening database connection", ex);
throw;
}
}
The API definition for the delete service is:
[Tag("App")]
[ValidateIsAuthenticated]
[ValidateHasRole("MANAGE.DATA")]
[Route("/app/Configuration/{Id}", "DELETE")]
[AutoApply(MyAuditBehavior.MyAuditDelete)]
public class DeleteConfiguration : IDeleteDb<Configuration>, IReturn<DeleteResponse>, IDelete
{
public Guid Id { get; set; } = Guid.Empty;
}
public class DeleteResponse
{
public Guid Id { get; set; } = Guid.Empty;
public int Count { get; set; } = 0; // added to help trace error
public ResponseStatus? ResponseStatus { get; set; } = null;
}
When the service does not work, it fails at step 2, when the AutoQuery.Delete call returns no errors/exceptions, but the response2.Count = 0.
The record is still in the database table, with the relevant soft-delete values correctly updated by step 1 and my [AutoApply(MriAuditBehavior.MyAuditDelete)]
:
public static class MyAuditBehavior
{
public const string MyAuditQuery = "MyAuditQuery";
public const string MyAuditCreate = "MyAuditCreate";
public const string MyAuditUpdate = "MyAuditUpdate";
public const string MyAuditPatch = "MyAuditPatch";
public const string MyAuditDelete = "MyAuditDelete";
public const string MyAuditSoftDelete = "MyAuditSoftDelete";
}
public class MyDatabaseAuditBehavior
{
public static void MyAuditFilter(AutoCrudMetadata meta)
{
if (meta.HasAutoApply(MyAuditBehavior.MyAuditCreate))
{
AppyMyBehavior(meta, "CreatedDataEventId");
}
if (meta.HasAutoApply(MyAuditBehavior.MyAuditUpdate))
{
AppyMyBehavior(meta, "UpdatedDataEventId");
}
if (meta.HasAutoApply(MyAuditBehavior.MyAuditPatch))
{
AppyMyBehavior(meta, "UpdatedDataEventId");
}
if (meta.HasAutoApply(MyAuditBehavior.MyAuditSoftDelete))
{
AppyMyBehavior(meta, "DeletedDataEventId");
}
if (meta.HasAutoApply(MyAuditBehavior.MyAuditDelete))
{
AppyMyBehavior(meta, "DeletedDataEventId");
}
}
private static void AppyMyBehavior(AutoCrudMetadata meta, string eventId)
{
meta.Add(new AutoPopulateAttribute(nameof(IAudit.DataEventOn))
{
Eval = "utcNow"
});
meta.Add(new AutoPopulateAttribute(nameof(IAudit.DataEventBy))
{
Eval = "userSession.AccountId"
});
meta.Add(new AutoPopulateAttribute(nameof(IAudit.DataEventId))
{
Eval = eventId
});
}
}
I am sure I am doing something wrong, but I do not really know enough yet, so any help appreciated.