Hi, I'm using Postgres and I'd to prevent user delete Customer record if that record alread used in SalesOrder Table. I already defined the foreignkey in SalesOrder as the below code, but there is no happen when I deleted customer. I expected an exception message will be thrown when I delete a customer already used in dependent tables.
b.ToTable(OrderManagmentDbProperties.DbTablePrefix + "SalesOrders", OrderManagmentDbProperties.DbSchema);
b.ConfigureByConvention();
b.Property(x => x.OrderNumber).HasColumnName(nameof(SalesOrder.OrderNumber)).IsRequired().HasMaxLength(SalesOrderConsts.OrderNumberMaxLength);
b.Property(x => x.OrderDate).HasColumnName(nameof(SalesOrder.OrderDate));
b.Property(x => x.Status).HasColumnName(nameof(SalesOrder.Status));
b.Property(x => x.SalesPerson).HasColumnName(nameof(SalesOrder.SalesPerson)).HasMaxLength(SalesOrderConsts.SalesPersonMaxLength);
b.Property(x => x.TotalAmount).HasColumnName(nameof(SalesOrder.TotalAmount));
b.HasOne<Customer>().WithMany().IsRequired().HasForeignKey(x => x.CustomerId).OnDelete(DeleteBehavior.SetNull);
});
Please help me for this issue. Thanks, Dharmar (Han Nguyen)
10 Answer(s)
-
0
Hey,
your foreign key probably does not prevent deletion because your customer entity has soft delete enabled. That means the record ist still in the db after you delete it and the foreign key stays intact.
Depending on your architecture, you can either fire off an event and prevent deletion somewhere, or guard against deletion inside of the appservice which deletes the customer - for example by checking the order repository for existing entries on the customer to delete.
You may take a look at ABP's free DDD e-book for inspiration on Implementation.
Long story short, you just need to ensure that your data stays consistent inside your code. Implementation needs to match your specific requirements and architecture.
Please let me know if that helps.
Kind regards Jack
-
0
Thanks Jack a lot, I already remove soft delete for Customer and system already thrown the exception message. Another question, how can we capture this except to show more friendly message to user, as currently the message is only "An internal error..." and user don't know what happened. Thanks, Dharma (Han Nguyen)
-
0
Hey Dharma,
You could throw a BusinessException or a UserFriendlyException.
Keep note that in your approach you would most likely need to override the DeleteAsync-method and wrap a try-catch around deletion of the entity, to then be able to even catch the FK-Exception.
kind regards Jack
-
0
Thanks Jack, I will try as you advised.
-
0
Hi Jack, I did as you recommended, I tried to add try... catch in DeleteAsync in ApplicationService but when I debug it always by passed. I only can catch the exception in blazor page but there is no detail to help me check is it FGK exception or not. How and where can I catch this exception so that I can get the detail error and check if it is FGK exception I will throw a friendly message to user. Thanks, Daharma (Han Nguyen)
-
0
Hi,
that's probably because of the UOW.
try this:
await _productRepository.DeleteAsync(id, autoSave: true);
-
0
-
0
-
0
Hey,
here it is: https://github.com/nebula2/abp-qa-5459
take a look at the app service here https://github.com/nebula2/abp-qa-5459/blob/master/src/Qa5459.Application/Entities/ParentEntityAppService.cs
Please note, that ensuring business logic consistency through foreign key constraints - and trying to handle such exceptions inside the application layer is most likely not a good practice.
-
0
Thanks a lot for your support, I will try your code.