Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use DbFunction for global query filters. #20065

Merged
merged 3 commits into from
Jun 25, 2024
Merged

Use DbFunction for global query filters. #20065

merged 3 commits into from
Jun 25, 2024

Conversation

maliming
Copy link
Member

@maliming maliming commented Jun 18, 2024

Resolve #20062

public class Book : FullAuditedEntity<Guid>, IMultiTenant ,IIsActive
{
    public string Name { get; set; }
    public bool IsActive { get; set; } //Defined by IIsActive
    public Guid? TenantId { get; set; } 
}

var books = await _bookRepository.GetListAsync();

using (_isActiveFilter.Disable())
{
    books = await _bookRepository.GetListAsync();
    using (_multiTenantFilter.Disable())
    {
        books = await _bookRepository.GetListAsync();
        using (_softDeleteFilter.Disable())
        {
            books = await _bookRepository.GetListAsync();
        }
    }
}

SELECT * FROM [AppBooks] AS [a] WHERE (@__ef_filter__p_0 = CAST(1 AS bit) OR [a].[IsDeleted] = CAST(0 AS bit)) AND (@__ef_filter__p_1 = CAST(1 AS bit) OR [a].[TenantId] = @__ef_filter__CurrentTenantId_2) AND (@__ef_filter__p_3 = CAST(1 AS bit) OR [a].[IsActive] = CAST(1 AS bit))

The generated SQL doesn't change when the filter is disabled/enabled, only the variables are changed

(@__ef_filter__p_0 = CAST(1 AS bit) OR [a].[IsDeleted] = CAST(0 AS bit)) AND (@__ef_filter__p_1 = CAST(1 AS bit) OR [a].[TenantId] = @__ef_filter__CurrentTenantId_2) AND (@__ef_filter__p_3 = CAST(1 AS bit) OR [a].[IsActive] = CAST(1 AS bit)) may causing high CPU usage.


After this PR, The SQL is now more precise(tested in MySQL, PostgreSQL, SQLite).

var books = await _bookRepository.GetListAsync(); 
// SELECT * FROM [AppBooks] AS [a] WHERE 
// [a].[IsDeleted] = CAST(0 AS bit) AND
// [a].[TenantId] = @__ef_filter__CurrentTenantId_0 AND
// [a].[IsActive] = CAST(1 AS bit)

using (_isActiveFilter.Disable())
{
    books = await _bookRepository.GetListAsync();
    // SELECT * FROM [AppBooks] AS [a] WHERE 
    // [a].[IsDeleted] = CAST(0 AS bit) AND 
    // [a].[TenantId] = @__ef_filter__CurrentTenantId_0

    using (_multiTenantFilter.Disable())
    {
        books = await _bookRepository.GetListAsync();
        // SELECT * FROM [AppBooks] AS [a] WHERE 
        // [a].[IsDeleted] = CAST(0 AS bit)

        using (_softDeleteFilter.Disable())
        {
            books = await _bookRepository.GetListAsync();
            // SELECT * FROM [AppBooks] AS [a]
        }
    }
}

@maliming maliming added this to the 8.3-preview milestone Jun 18, 2024
@maliming maliming marked this pull request as draft June 18, 2024 05:22
@hikalkan hikalkan merged commit d1692fe into dev Jun 25, 2024
4 checks passed
@hikalkan hikalkan deleted the DbFunction branch June 25, 2024 06:58
@hikalkan
Copy link
Member

Thanks 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Use DbFunction for global query filters
3 participants