Open Closed

How to prevent user to delete the principle entity record if it is used in the dependent entities? #5459


User avatar
0
hanntd created

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)
  • User Avatar
    0
    jfistelmann created

    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

  • User Avatar
    0
    hanntd created

    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)

  • User Avatar
    0
    jfistelmann created

    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

  • User Avatar
    0
    hanntd created

    Thanks Jack, I will try as you advised.

  • User Avatar
    0
    hanntd created

    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)

  • User Avatar
    0
    jfistelmann created

    Hi,

    that's probably because of the UOW.

    try this:

    await _productRepository.DeleteAsync(id, autoSave: true);
    
  • User Avatar
    0
    hanntd created

    I have done as you recommended and it threw another exception:

  • User Avatar
    0
    jfistelmann created

    I have done as you recommended and it threw another exception:

    I will create an example repo and share the github link. I think that would be best.

  • User Avatar
    0
    jfistelmann created

    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.

  • User Avatar
    0
    hanntd created

    Thanks a lot for your support, I will try your code.

Made with ❤️ on ABP v8.2.0-preview Updated on March 25, 2024, 15:11