Base solution for your next web application
Open Closed

Unit of work #3277


User avatar
0
imad created

Hi,

In my application service i need to connect to an external database using ODBC, this database provider doesn't support transaction, and it causing problem with the default transnational nature of application service methods.

The solution was to add the [UnitOfWork(IsDisabled = true)] attribute and define my own scope for the code part that needs to interact with the SQL server database using UnitOfWorkManager.Begin() method. However the behavior I am getting is different if I execute the SQL server part alone in an application service methods.

What I Have so far:

[UnitOfWork(IsDisabled = true)]
public async Task DeleteObject(DeleteObjectInput input){
    //connect to external engine

    //perform SQL server logic
    var unitOfWorkOptions = new UnitOfWorkOptions() { IsTransactional = true };
    unitOfWorkOptions.FilterOverrides.Add(new DataFilterConfiguration(AbpDataFilters.SoftDelete, false));
    using (var unitOfWork = UnitOfWorkManager.Begin(unitOfWorkOptions))
    {
        var object = await _objectRepository.GetAsync(input.Id);
       //perform some logic
        await _objectRepository.DeleteAsync(object );
        await unitOfWork.CompleteAsync();
    }
}

The object class has a List of other sub-objects and a one to one relation with another extend-object. When i execute the above code only the object is marked as deleted and the dependent objects are intact, while if i execute the same code directly in an application service methods all the dependent object are marked as deleted.

Another point, I assume disabling the SoftDelete filter is enough to completely remove the objects from the database, which is not the case (apparently it works only on the select), do I need to execute a raw SQL query to achieve this behavior?

Thank you.


4 Answer(s)
  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    First you need to add

    unitOfWorkOptions.Scope = TransactionScopeOption.RequiresNew;
    

    to your unit of work options. In current version it uses app service's unit of work and your options probably is not used.

    But, ABP does not support cascade operations. It means, when you delete your object, related objects will not be marked as deleted automatically. You can use

    • delete related entities with their repositories
    • custom sql
    • or SQL Server's cascade delete option.

    Thanks.

  • User Avatar
    0
    imad created

    Hi,

    Changing the scope to RequiresNew, solved the problem and i am getting the same behavior as if i am executing in a default app service methods. My objects are using foreign keys with cascadedelete so the delete is automatically handled by EF.

    Is there any possible way to disable the SoftDelete filter while executing a delete to do a physical delete (check the second part of my question)?

    Thank you.

  • User Avatar
    0
    imad created

    Hi,

    I ended up overriding the CancelDeletionForSoftDelete in my dbContext:

    protected override void CancelDeletionForSoftDelete(System.Data.Entity.Infrastructure.DbEntityEntry entry)
            {
                if (!this.CurrentUnitOfWorkProvider.Current.IsFilterEnabled(Abp.Domain.Uow.AbpDataFilters.SoftDelete))
                {
                    return;
                }
    
                base.CancelDeletionForSoftDelete(entry);
            }
    
  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @imad,

    Sorry, I missed your second question. Thanks for sharing your solution :). It is the suggested wat #1728@3f2885ed-6ee5-4bb2-920b-f5a149e20745.