How to ignore ISoftDelete interface behavior for the related entities queries using EF Core and ABP?

630 Views Asked by At

I'm using EF Core and ISoftDelete of ABP for some entities. The global version of aspnetcore and EF Core is 2.1. ABP is 3.4.0

For each query to the database (for the ISoftDelete entity) that is not marked by IgnoreQueryFilters() ABP is adding to the resulting expression tree (and SQL therefore) something like where IsDeleted = 0. I noticed that it will be also added to the joined table in case of selecting any column of the related entity. Here are some code samples

public class User : EntityBase, ISoftDelete
{
    public string Name { get; set; }

    public bool IsDeleted { get; set; }
}

public class Manager : EntityBase, ISoftDelete
{
    public long UserId { get; set; }
    
    public virtual User User { get; set; }
    
    public bool IsDeleted { get; set; }
}

Here are query without selecting a related entity (User) and the resulting SQL from the profiler

var managerIds = _dbContext
    .Set<Manager>()
    .Select(x => new
    {
        ManagerId = x.Id
    })
    .ToArray();
SELECT [e].[Id] AS [ManagerId]
FROM [Managers] AS [e]
WHERE (([e].[IsDeleted] = 0) OR ([e].[IsDeleted] <> 1))

The code that excludes deleted lines was added automatically here and that's expected

Here is the query with a select from a related entity

var managerIdsWithUserNames = _dbContext
    .Set<Manager>()
    .Select(x => new
    {
        ManagerId = x.Id,
        UserName = x.User.Name
    })
    .ToArray();
SELECT [e].[Id] AS [ManagerId], [t].[Name] AS [UserName]
FROM [Managers] AS [e]
INNER JOIN (
    SELECT [e0].*
    FROM [Users] AS [e0]
    WHERE ([e0].[IsDeleted] = 0) OR ([e0].[IsDeleted] <> 1)
) AS [t] ON [e].[UserId] = [t].[Id]
WHERE (([e].[IsDeleted] = 0) OR ([e].[IsDeleted] <> 1))

But in this case, this where IsDeleted = 0 is added to the joined table and that's not what I expected nor what I needed.

As the result, I need to not exclude deleted Users in a query to the Managers and exclude deleted Managers. I know that I can fix it like this

var managerIdsWithUserNames = _dbContext
    .Set<Manager>()
    .IgnoreQueryFilters()
    .Where(x => !x.IsDeleted)
    .Select(x => new
    {
        ManagerId = x.Id,
        UserName = x.User.Name
    })
    .ToArray();

but it doesn't look like a general solution because there could be other related entities in one table.

So is it generally a correct behavior and is there a possibility to disable it for the related entities (extension method probably)?

Please feel free to leave comments and fix grammar.

0

There are 0 best solutions below