diff --git a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/IgnoreQueryFiltersEvaluator.cs b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/IgnoreQueryFiltersEvaluator.cs new file mode 100644 index 00000000..5cd64e4c --- /dev/null +++ b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/IgnoreQueryFiltersEvaluator.cs @@ -0,0 +1,26 @@ +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Ardalis.Specification.EntityFrameworkCore +{ + public class IgnoreQueryFiltersEvaluator : IEvaluator + { + private IgnoreQueryFiltersEvaluator() { } + public static IgnoreQueryFiltersEvaluator Instance { get; } = new IgnoreQueryFiltersEvaluator(); + + public bool IsCriteriaEvaluator { get; } = true; + + public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class + { + if (specification.IgnoreQueryFilters) + { + query = query.IgnoreQueryFilters(); + } + + return query; + } + } +} diff --git a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/SpecificationEvaluator.cs b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/SpecificationEvaluator.cs index bac4e813..102f383c 100644 --- a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/SpecificationEvaluator.cs +++ b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/SpecificationEvaluator.cs @@ -29,6 +29,7 @@ public SpecificationEvaluator(bool cacheEnabled = false) OrderEvaluator.Instance, PaginationEvaluator.Instance, AsNoTrackingEvaluator.Instance, + IgnoreQueryFiltersEvaluator.Instance, #if NETSTANDARD2_1 AsSplitQueryEvaluator.Instance, AsNoTrackingWithIdentityResolutionEvaluator.Instance diff --git a/Specification/src/Ardalis.Specification/Builder/SpecificationBuilderExtensions.cs b/Specification/src/Ardalis.Specification/Builder/SpecificationBuilderExtensions.cs index 9f1ef368..4b96153d 100644 --- a/Specification/src/Ardalis.Specification/Builder/SpecificationBuilderExtensions.cs +++ b/Specification/src/Ardalis.Specification/Builder/SpecificationBuilderExtensions.cs @@ -261,5 +261,21 @@ public static ISpecificationBuilder AsNoTrackingWithIdentityResolution( return specificationBuilder; } + + /// + /// The query will ignore the defined global query filters + /// + /// + /// for more info: https://docs.microsoft.com/en-us/ef/core/querying/filters + /// + /// + /// + public static ISpecificationBuilder IgnoreQueryFilters( + this ISpecificationBuilder specificationBuilder) where T : class + { + specificationBuilder.Specification.IgnoreQueryFilters = true; + + return specificationBuilder; + } } } diff --git a/Specification/src/Ardalis.Specification/ISpecification.cs b/Specification/src/Ardalis.Specification/ISpecification.cs index 09934a09..84875d5d 100644 --- a/Specification/src/Ardalis.Specification/ISpecification.cs +++ b/Specification/src/Ardalis.Specification/ISpecification.cs @@ -112,6 +112,14 @@ public interface ISpecification /// bool AsNoTrackingWithIdentityResolution { get; } + /// + /// Returns whether or not the query should ignore the defined global query filters + /// + /// + /// for more info: https://docs.microsoft.com/en-us/ef/core/querying/filters + /// + bool IgnoreQueryFilters { get; } + /// /// Applies the query defined within the specification to the given objects. /// This is specially helpful when unit testing specification classes diff --git a/Specification/src/Ardalis.Specification/Specification.cs b/Specification/src/Ardalis.Specification/Specification.cs index bf23557a..0359d58d 100644 --- a/Specification/src/Ardalis.Specification/Specification.cs +++ b/Specification/src/Ardalis.Specification/Specification.cs @@ -94,5 +94,8 @@ public virtual IEnumerable Evaluate(IEnumerable entities) /// public bool AsNoTrackingWithIdentityResolution { get; internal set; } = false; + + /// + public bool IgnoreQueryFilters { get; internal set; } = false; } } \ No newline at end of file diff --git a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_IgnoreQueryFilters.cs b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_IgnoreQueryFilters.cs new file mode 100644 index 00000000..b2238e92 --- /dev/null +++ b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_IgnoreQueryFilters.cs @@ -0,0 +1,25 @@ +using Ardalis.Specification.UnitTests.Fixture.Specs; +using FluentAssertions; +using Xunit; + +namespace Ardalis.Specification.UnitTests.BuilderTests +{ + public class SpecificationBuilderExtensions_IgnoreQueryFilters + { + [Fact] + public void DoesNothing_GivenSpecWithoutIgnoreQueryFilters() + { + var spec = new StoreEmptySpec(); + + spec.IgnoreQueryFilters.Should().Be(false); + } + + [Fact] + public void FlagsIgnoreQueryFilters_GivenSpecWithIgnoreQueryFilters() + { + var spec = new CompanyByIdIgnoreQueryFilters(1); + + spec.IgnoreQueryFilters.Should().Be(true); + } + } +} diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdIgnoreQueryFilters.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdIgnoreQueryFilters.cs new file mode 100644 index 00000000..8910221e --- /dev/null +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdIgnoreQueryFilters.cs @@ -0,0 +1,15 @@ +using Ardalis.Specification.UnitTests.Fixture.Entities; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Ardalis.Specification.UnitTests.Fixture.Specs +{ + public class CompanyByIdIgnoreQueryFilters : Specification, ISingleResultSpecification + { + public CompanyByIdIgnoreQueryFilters(int id) + { + Query.Where(company => company.Id == id).IgnoreQueryFilters(); + } + } +}