Skip to content

Conversation

@fiseni
Copy link
Collaborator

@fiseni fiseni commented Dec 21, 2021

Closes #143. This should be merged after PR #191.

All specification builder methods got an overload that accepts bool condition parameter. If this condition is false, the given expression/value is discarded and is not added to the specification. I decided not to implement it as an optional parameter, since that might be a breaking change for someone. The Select and PostProcessingAction methods are an exception, and those methods won't have an overload with this parameter. Once the specification is defined with generic parameters<T, TResult>, then it must contain a selector.

Sample Usage:

public class CustomerSpec : Specification<Customer>
{
    // Instead of having this
    public CustomerSpec(CustomerFilter filter)
    {
        if (!string.IsNullOrEmpty(filter.Name))
            Query.Where(x => x.Name == filter.Name);

        if (!string.IsNullOrEmpty(filter.Email))
            Query.Where(x => x.Email == filter.Email);

        if (!string.IsNullOrEmpty(filter.Address))
            Query.Search(x => x.Address, "%" + filter.Address + "%");
    }

    // Users can do this
    public CustomerSpec(CustomerFilter filter)
    {
        Query
            .Where(x => x.Name == filter.Name, !string.IsNullOrEmpty(filter.Name))
            .Where(x => x.Email == filter.Email, !string.IsNullOrEmpty(filter.Email))
            .Search(x => x.Address, "%" + filter.Address + "%", !string.IsNullOrEmpty(filter.Address));
    }
}

Since the Include and Order methods offer multi-level chaining, if the parent method has false condition, the whole chain afterward is discarded.

public class CompanyByIdWithFalseConditions : Specification<Company>, ISingleResultSpecification
{
    public CompanyByIdWithFalseConditions(int id)
    {
        Query.Where(x => x.Id == id, false)
            .OrderBy(x => x.Id, false)
                .ThenBy(x => x.Name) // since the parent is not added, this also will be discarded
            .Include(x => x.Stores, false)
                .ThenInclude(x => x.Products); // since the parent is not added, this also will be discarded
    }
}

public class CompanyByIdWithFalseConditionsForInnerChains : Specification<Company>, ISingleResultSpecification
{
    public CompanyByIdWithFalseConditionsForInnerChains(int id)
    {
        Query.Where(x => x.Id == id, false)
            .OrderBy(x => x.Id) // it will be added
                .ThenBy(x => x.Name, false) // it won't be added
                .ThenByDescending(x => x.Name) // since the parent is not added, this also will be discarded
            .Include(x => x.Stores) // it will be added
                .ThenInclude(x => x.Products, false) // it won't be added
                .ThenInclude(x => x.Origin) // since the parent is not added, this also will be discarded
    }
}

@fiseni fiseni requested a review from ardalis December 21, 2021 19:41
@ardalis
Copy link
Owner

ardalis commented Jan 12, 2022

Add to docs. 2nd parameter, if false, means the expression will not be added.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Can multi-condition query add WhereIf extension similar to abp

3 participants