From 5aac6d9fedc80a65ac90b8f1644eef3ecf3c4e73 Mon Sep 17 00:00:00 2001 From: Fati Iseni Date: Fri, 21 Jul 2023 13:53:02 +0200 Subject: [PATCH 1/3] Updated LangVErsion. Consolidated styling and conventions. --- .editorconfig | 162 ++- .github/workflows/build-test-ef6.yml | 2 +- .github/workflows/build-test.yml | 4 +- .github/workflows/publish.yml | 2 +- .github/workflows/publishef6.yml | 2 +- .github/workflows/publishefcore.yml | 2 +- Ardalis.Specification.sln | 8 +- Dockerfile | 6 +- ...alis.Specification.EntityFramework6.csproj | 40 +- .../Evaluators/AsNoTrackingEvaluator.cs | 25 +- .../Evaluators/IncludeEvaluator.cs | 41 +- .../Evaluators/OrderEvaluator.cs | 137 ++- .../Evaluators/SearchEvaluator.cs | 25 +- .../Evaluators/SpecificationEvaluator.cs | 87 +- .../Extensions/DbSetExtensions.cs | 83 +- .../Extensions/IncludeExtensions.cs | 83 +- .../Extensions/ParameterReplacerVisitor.cs | 40 +- .../Extensions/SearchExtension.cs | 73 +- .../Properties/AssemblyInfo.cs | 1 - .../RepositoryBaseOfT.cs | 317 +++--- ...n.EntityFramework6.IntegrationTests.csproj | 33 +- .../Configurations/AddressConfiguration.cs | 17 +- .../Configurations/CompanyConfiguration.cs | 25 +- .../Configurations/CountryConfiguration.cs | 17 +- .../Configurations/ProductConfiguration.cs | 17 +- .../Configurations/StoreConfiguration.cs | 21 +- .../Fixture/DbInitializer.cs | 29 +- .../Fixture/IntegrationTestBase.cs | 23 +- .../Fixture/RepositoryOfT.cs | 17 +- .../Fixture/SharedDatabaseFixture.cs | 59 +- .../Fixture/TestDbContext.cs | 49 +- .../Properties/AssemblyInfo.cs | 1 - .../RepositoryOfT_AnyAsync.cs | 47 +- .../RepositoryOfT_GetById.cs | 39 +- .../RepositoryOfT_GetBySpec.cs | 189 ++-- .../RepositoryOfT_ListAsync.cs | 303 +++--- ...s.Specification.EntityFrameworkCore.csproj | 49 +- .../CachedReadConcurrentDictionary.cs | 368 ++++--- .../ContextFactoryRepositoryBaseOfT.cs | 456 +++++---- .../EFRepositoryFactory.cs | 54 +- .../Evaluators/AsNoTrackingEvaluator.cs | 31 +- ...TrackingWithIdentityResolutionEvaluator.cs | 33 +- .../Evaluators/AsSplitQueryEvaluator.cs | 33 +- .../Evaluators/AsTrackingEvaluator.cs | 31 +- .../Evaluators/IgnoreQueryFiltersEvaluator.cs | 36 +- .../Evaluators/IncludeEvaluator.cs | 297 +++--- .../Evaluators/SearchEvaluator.cs | 25 +- .../Evaluators/SpecificationEvaluator.cs | 111 +-- .../Extensions/DbSetExtensions.cs | 89 +- .../Extensions/ParameterReplacerVisitor.cs | 40 +- .../Extensions/SearchExtension.cs | 94 +- .../IRepositoryFactory.cs | 27 +- .../RepositoryBaseOfT.cs | 402 ++++---- ...ntityFrameworkCore.IntegrationTests.csproj | 34 +- .../ContextFactoryRepositoryBaseOfTTests.cs | 212 ++-- .../EFRepositoryFactoryTests.cs | 168 ++-- .../Fixture/ContextFactoryRepositoryOfT.cs | 19 +- .../Fixture/GetCompanyWithStoresSpec.cs | 11 +- .../Fixture/IntegrationTestBase.cs | 23 +- .../Fixture/LoggerFactoryProvider.cs | 20 +- .../Fixture/RepositoryOfT.cs | 23 +- .../Fixture/SharedDatabaseFixture.cs | 121 ++- .../Fixture/TestDbContext.cs | 56 +- .../RepositoryOfT_AnyAsync.cs | 62 +- .../RepositoryOfT_AsAsyncEnumerable.cs | 76 +- .../RepositoryOfT_GetById.cs | 54 +- .../RepositoryOfT_GetBySpec.cs | 201 ++-- .../RepositoryOfT_ListAsync.cs | 323 +++--- ...ation.EntityFrameworkCore.UnitTests.csproj | 30 - .../EFRepositoryFactoryTests.cs | 27 - .../Ardalis.Specification.csproj | 39 +- .../Builder/CacheSpecificationBuilder.cs | 27 +- .../Builder/ICacheSpecificationBuilder.cs | 9 +- .../IIncludableSpecificationBuilder.cs | 11 +- .../Builder/IOrderedSpecificationBuilder.cs | 12 +- .../Builder/ISpecificationBuilder.cs | 20 +- .../Builder/IncludableBuilderExtensions.cs | 79 +- .../Builder/IncludableSpecificationBuilder.cs | 29 +- .../Builder/OrderedBuilderExtensions.cs | 78 +- .../Builder/OrderedSpecificationBuilder.cs | 30 +- .../Builder/SpecificationBuilder.cs | 34 +- .../Builder/SpecificationBuilderExtensions.cs | 941 +++++++++--------- .../Evaluators/IEvaluator.cs | 16 +- .../Evaluators/IInMemoryEvaluator.cs | 14 +- .../IInMemorySpecificationEvaluator.cs | 16 +- .../Evaluators/ISpecificationEvaluator.cs | 46 +- .../InMemorySpecificationEvaluator.cs | 85 +- .../Evaluators/OrderEvaluator.cs | 123 ++- .../Evaluators/PaginationEvaluator.cs | 61 +- .../Evaluators/SearchEvaluator.cs | 23 +- .../Evaluators/SearchExtension.cs | 215 ++-- .../Evaluators/WhereEvaluator.cs | 39 +- .../ConcurrentSelectorsException.cs | 23 +- .../DuplicateOrderChainException.cs | 26 +- .../Exceptions/DuplicateSkipException.cs | 25 +- .../Exceptions/DuplicateTakeException.cs | 25 +- .../InvalidSearchPatternException.cs | 25 +- .../Exceptions/SelectorNotFoundException.cs | 23 +- .../Expressions/IncludeExpressionInfo.cs | 143 ++- .../Expressions/OrderExpressionInfo.cs | 71 +- .../Expressions/SearchExpressionInfo.cs | 89 +- .../Expressions/WhereExpressionInfo.cs | 51 +- .../src/Ardalis.Specification/IEntity.cs | 9 +- .../IReadRepositoryBase.cs | 337 ++++--- .../Ardalis.Specification/IRepositoryBase.cs | 118 ++- .../ISingleResultSpecification.cs | 49 +- .../Ardalis.Specification/ISpecification.cs | 295 +++--- .../Ardalis.Specification/IncludeTypeEnum.cs | 13 +- .../Ardalis.Specification/OrderTypeEnum.cs | 23 +- .../SingleResultSpecification.cs | 17 +- .../Ardalis.Specification/Specification.cs | 179 ++-- .../Validators/ISpecificationValidator.cs | 11 +- .../Validators/IValidator.cs | 11 +- .../Validators/SearchValidator.cs | 28 +- .../Validators/SpecificationValidator.cs | 51 +- .../Validators/WhereValidator.cs | 25 +- .../Ardalis.Specification.UnitTests.csproj | 28 +- ...IncludableBuilderExtensions_ThenInclude.cs | 70 +- .../OrderedBuilderExtensions_ThenBy.cs | 60 +- ...deredBuilderExtensions_ThenByDescending.cs | 60 +- ...ificationBuilderExtensions_AsNoTracking.cs | 53 +- ...ions_AsNoTrackingWithIdentityResolution.cs | 53 +- ...ificationBuilderExtensions_AsSplitQuery.cs | 41 +- ...ecificationBuilderExtensions_AsTracking.cs | 53 +- ...ionBuilderExtensions_IgnoreQueryFilters.cs | 41 +- .../SpecificationBuilderExtensions_Include.cs | 48 +- ...ficationBuilderExtensions_IncludeString.cs | 50 +- .../SpecificationBuilderExtensions_OrderBy.cs | 48 +- ...tionBuilderExtensions_OrderByDescending.cs | 48 +- ...nBuilderExtensions_PostProcessingAction.cs | 60 +- .../SpecificationBuilderExtensions_Search.cs | 88 +- .../SpecificationBuilderExtensions_Select.cs | 34 +- ...ecificationBuilderExtensions_SelectMany.cs | 29 +- .../SpecificationBuilderExtensions_Skip.cs | 62 +- .../SpecificationBuilderExtensions_Take.cs | 48 +- .../SpecificationBuilderExtensions_Where.cs | 60 +- .../InMemorySpecificationEvaluatorTests.cs | 222 ++--- .../SearchEvaluator_Evaluate.cs | 77 +- .../EvaluatorTests/SearchExtension_Like.cs | 171 ++-- .../ConcurrentSelectorsExceptionTests.cs | 35 +- .../DuplicateOrderChainExceptionTests.cs | 37 +- .../DuplicateSkipExceptionTests.cs | 37 +- .../DuplicateTakeExceptionTests.cs | 37 +- .../InvalidSearchPatternExceptionTests.cs | 39 +- .../SelectorNotFoundExceptionTests.cs | 35 +- .../Fixture/Entities/Address.cs | 23 +- .../Fixture/Entities/Company.cs | 21 +- .../Fixture/Entities/Country.cs | 17 +- .../Fixture/Entities/Product.cs | 17 +- .../Fixture/Entities/Seeds/AddressSeed.cs | 37 +- .../Fixture/Entities/Seeds/CompanySeed.cs | 38 +- .../Fixture/Entities/Seeds/CountrySeed.cs | 37 +- .../Fixture/Entities/Seeds/ProductSeed.cs | 47 +- .../Fixture/Entities/Seeds/StoreSeed.cs | 118 ++- .../Fixture/Entities/Store.cs | 29 +- .../Fixture/Specs/CompanyByIdAsSplitQuery.cs | 17 +- .../Fixture/Specs/CompanyByIdAsTrackedSpec.cs | 11 +- .../Specs/CompanyByIdAsUntrackedSpec.cs | 11 +- ...IdAsUntrackedWithIdentityResolutionSpec.cs | 11 +- .../Specs/CompanyByIdIgnoreQueryFilters.cs | 11 +- ...ByIdIncludeStoresThenIncludeAddressSpec.cs | 15 +- ...yIdIncludeStoresThenIncludeProductsSpec.cs | 15 +- .../Fixture/Specs/CompanyByIdSpec.cs | 11 +- ...ompanyByIdWithAsNoTrackingAsTrackedSpec.cs | 11 +- ...ompanyByIdWithAsTrackingAsUntrackedSpec.cs | 11 +- ...ngAsUntrackedWithIdentityResolutionSpec.cs | 13 +- .../Specs/CompanyByIdWithFalseConditions.cs | 45 +- ...nyByIdWithFalseConditionsForInnerChains.cs | 47 +- .../Fixture/Specs/StoreByIdAndNameSpec.cs | 13 +- .../StoreByIdIncludeAddressAndProductsSpec.cs | 15 +- .../Specs/StoreByIdIncludeAddressSpec.cs | 13 +- ...ompanyAndCountryAndStoresForCompanySpec.cs | 15 +- .../Specs/StoreByIdIncludeProductsSpec.cs | 13 +- ...StoreByIdIncludeProductsUsingStringSpec.cs | 13 +- .../Specs/StoreByIdSearchByNameAndCitySpec.cs | 15 +- .../Specs/StoreByIdSearchByNameOrCitySpec.cs | 15 +- .../Fixture/Specs/StoreByIdSpec.cs | 11 +- .../Fixture/Specs/StoreDuplicateSkipSpec.cs | 13 +- .../Fixture/Specs/StoreDuplicateTakeSpec.cs | 13 +- .../Fixture/Specs/StoreEmptySpec.cs | 9 +- .../Fixture/Specs/StoreNamesEmptySpec.cs | 9 +- .../Fixture/Specs/StoreNamesPaginatedSpec.cs | 17 +- .../Fixture/Specs/StoreNamesSpec.cs | 11 +- .../StoreNamesWithPostProcessingActionSpec.cs | 13 +- .../Specs/StoreProductNamesEmptySpec.cs | 9 +- .../Fixture/Specs/StoreProductNamesSpec.cs | 12 +- .../Specs/StoreSearchByNameAndCitySpec.cs | 13 +- .../Specs/StoreSearchByNameOrCitySpec.cs | 13 +- .../Fixture/Specs/StoreSearchByNameSpec.cs | 11 +- .../StoreWithPostProcessingActionSpec.cs | 11 +- .../StoresByCompanyOrderedDescByNameSpec.cs | 13 +- ...ompanyOrderedDescByNameThenByDescIdSpec.cs | 15 +- ...sByCompanyOrderedDescByNameThenByIdSpec.cs | 15 +- ...ByCompanyPaginatedOrderedDescByNameSpec.cs | 21 +- .../Specs/StoresByCompanyPaginatedSpec.cs | 17 +- .../Fixture/Specs/StoresByIdListSpec.cs | 13 +- .../StoresOrderedDescendingByNameSpec.cs | 11 +- .../Fixture/Specs/StoresOrderedSpecByName.cs | 11 +- .../Specs/StoresOrderedTwoChainsSpec.cs | 13 +- .../Fixture/Specs/StoresPaginatedSpec.cs | 15 +- .../CompanyIncludeFilteredStoresSpec.cs | 17 +- .../StoreIncludeAddressAndProductsSpec.cs | 16 +- .../StoreIncludeAddressSpec.cs | 14 +- ...reIncludeCompanyCountryDotSeparatedSpec.cs | 14 +- ...reIncludeCompanyThenCountryAsStringSpec.cs | 14 +- .../StoreIncludeCompanyThenCountrySpec.cs | 16 +- .../StoreIncludeCompanyThenNameSpec.cs | 16 +- .../StoreIncludeCompanyThenStoresSpec.cs | 15 +- .../StoreIncludeMethodOfNavigationSpec.cs | 14 +- .../StoreIncludeMethodSpec.cs | 14 +- .../StoreIncludeNameSpec.cs | 14 +- .../StoreIncludeProductsSpec.cs | 14 +- .../StoreWithFaultyIncludeSpec.cs | 14 +- .../GlobalUsings.cs | 5 + .../IncludeExpressionInfoTests.cs | 90 +- .../SpecificationValidator_Tests.cs | 127 ++- docker-compose.yml | 2 +- .../Ardalis.SampleApp.Core.csproj | 1 + .../Entities/CustomerAggregate/Customer.cs | 75 +- .../Entities/CustomerAggregate/Store.cs | 25 +- .../Entities/Seeds/CustomerSeed.cs | 31 +- .../Interfaces/IAggregateRoot.cs | 7 +- .../Interfaces/ICustomerRepository.cs | 15 +- .../Interfaces/IRepository.cs | 17 +- .../Specifications/CustomerByNameSpec.cs | 21 +- .../CustomerByNameWithStoresSpec.cs | 21 +- .../Specifications/CustomerSpec.cs | 41 +- .../Specifications/Filters/BaseFilter.cs | 17 +- .../Specifications/Filters/CustomerFilter.cs | 15 +- .../Specifications/PaginationHelper.cs | 43 +- .../Ardalis.SampleApp.Infrastructure.csproj | 1 + .../Data/CachedCustomerRepository.cs | 34 +- .../Data/CustomerRepository.cs | 8 +- .../Configurations/CustomerConfiguration.cs | 5 +- .../Configurations/StoreConfiguration.cs | 5 +- .../DataAccess/SampleDbContextSeed.cs | 8 +- .../Ardalis.SampleApp.Web.csproj | 8 +- .../Ardalis.SampleApp.Web/AutomapperMaps.cs | 6 +- .../Controllers/CustomersController.cs | 6 +- .../Interfaces/ICustomerUiService.cs | 4 +- .../Models/BaseFilterDto.cs | 6 +- .../Models/CustomerDto.cs | 5 +- .../Models/CustomerFilterDto.cs | 9 +- .../Ardalis.SampleApp.Web/Models/StoreDto.cs | 7 +- .../Pages/Index.cshtml.cs | 8 +- sample/Ardalis.SampleApp.Web/Program.cs | 6 +- .../Services/CustomerUiService.cs | 6 +- 247 files changed, 6118 insertions(+), 6793 deletions(-) delete mode 100644 Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.UnitTests/Ardalis.Specification.EntityFrameworkCore.UnitTests.csproj delete mode 100644 Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.UnitTests/EFRepositoryFactoryTests.cs create mode 100644 Specification/tests/Ardalis.Specification.UnitTests/GlobalUsings.cs diff --git a/.editorconfig b/.editorconfig index 0ee58191..d7f77f43 100644 --- a/.editorconfig +++ b/.editorconfig @@ -5,9 +5,21 @@ # All files [*] indent_style = space + +# Standard properties +end_of_line = crlf + +# XML project files +[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}] +indent_size = 2 + +# XML config files +[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}] +indent_size = 2 + # Code files [*.{cs,csx,vb,vbx}] -indent_size =2 +indent_size = 2 insert_final_newline = true charset = utf-8-bom ############################### @@ -15,22 +27,22 @@ charset = utf-8-bom ############################### [*.{cs,vb}] # Organize usings -dotnet_sort_system_directives_first = true +dotnet_sort_system_directives_first = false # this. preferences -dotnet_style_qualification_for_field = false:silent -dotnet_style_qualification_for_property = false:silent -dotnet_style_qualification_for_method = false:silent -dotnet_style_qualification_for_event = false:silent +dotnet_style_qualification_for_field = false:warning +dotnet_style_qualification_for_property = false:warning +dotnet_style_qualification_for_method = false:warning +dotnet_style_qualification_for_event = false:warning # Language keywords vs BCL types preferences -dotnet_style_predefined_type_for_locals_parameters_members = true:silent -dotnet_style_predefined_type_for_member_access = true:silent +dotnet_style_predefined_type_for_locals_parameters_members = true:warning +dotnet_style_predefined_type_for_member_access = true:warning # Parentheses preferences dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent # Modifier preferences -dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent +dotnet_style_require_accessibility_modifiers = for_non_interface_members:warning dotnet_style_readonly_field = true:suggestion # Expression-level preferences dotnet_style_object_initializer = true:suggestion @@ -38,35 +50,96 @@ dotnet_style_collection_initializer = true:suggestion dotnet_style_explicit_tuple_names = true:suggestion dotnet_style_null_propagation = true:suggestion dotnet_style_coalesce_expression = true:suggestion -dotnet_style_prefer_is_null_check_over_reference_equality_method = true:silent +dotnet_style_prefer_is_null_check_over_reference_equality_method = true:warning dotnet_style_prefer_inferred_tuple_names = true:suggestion dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion -dotnet_style_prefer_auto_properties = true:silent -dotnet_style_prefer_conditional_expression_over_assignment = true:silent -dotnet_style_prefer_conditional_expression_over_return = true:silent -# Namespace preferences -csharp_style_namespace_declarations = file_scoped:warning +dotnet_style_prefer_auto_properties = true:suggestion +dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion +dotnet_style_prefer_conditional_expression_over_return = true:suggestion ############################### # Naming Conventions # ############################### -# Style Definitions -dotnet_naming_style.pascal_case_style.capitalization = pascal_case -# Use PascalCase for constant fields -dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion -dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields -dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style -dotnet_naming_symbols.constant_fields.applicable_kinds = field -dotnet_naming_symbols.constant_fields.applicable_accessibilities = * -dotnet_naming_symbols.constant_fields.required_modifiers = const -tab_width=2 +# Non-private static fields are PascalCase +dotnet_naming_rule.non_private_static_fields_should_be_pascal_case.severity = error +dotnet_naming_rule.non_private_static_fields_should_be_pascal_case.symbols = non_private_static_fields +dotnet_naming_rule.non_private_static_fields_should_be_pascal_case.style = non_private_static_field_style +dotnet_naming_symbols.non_private_static_fields.applicable_kinds = field +dotnet_naming_symbols.non_private_static_fields.applicable_accessibilities = public, protected, internal, protected internal, private protected +dotnet_naming_symbols.non_private_static_fields.required_modifiers = static +dotnet_naming_style.non_private_static_field_style.capitalization = pascal_case +# Constants are PascalCase +dotnet_naming_rule.constants_should_be_pascal_case.severity = error +dotnet_naming_rule.constants_should_be_pascal_case.symbols = constants +dotnet_naming_rule.constants_should_be_pascal_case.style = camel_case_underscore_style +dotnet_naming_symbols.constants.applicable_kinds = field, local +dotnet_naming_symbols.constants.required_modifiers = const +dotnet_naming_style.constant_style.capitalization = pascal_case +# Public fields are Pascal case +dotnet_naming_symbols.public_fields.applicable_kinds = field +dotnet_naming_symbols.public_fields.applicable_accessibilities = public +dotnet_naming_rule.public_fields_should_be_pascal_case.severity = error +dotnet_naming_rule.public_fields_should_be_pascal_case.symbols = public_fields +dotnet_naming_rule.public_fields_should_be_pascal_case.style = pascal_case +# Static fields are camelCase +dotnet_naming_rule.static_fields_should_be_camel_case.severity = error +dotnet_naming_rule.static_fields_should_be_camel_case.symbols = static_fields +dotnet_naming_rule.static_fields_should_be_camel_case.style = camel_case_style +dotnet_naming_symbols.static_fields.applicable_kinds = field +dotnet_naming_symbols.static_fields.required_modifiers = static +dotnet_naming_symbols.static_fields.required_modifiers = none +dotnet_naming_style.static_field_style.capitalization = camel_case +# Instance fields are camelCase and start with _ +dotnet_naming_rule.camel_case_for_private_internal_fields.severity = error +dotnet_naming_rule.camel_case_for_private_internal_fields.symbols = private_internal_fields +dotnet_naming_rule.camel_case_for_private_internal_fields.style = camel_case_underscore_style +dotnet_naming_symbols.private_internal_fields.applicable_kinds = field +dotnet_naming_symbols.private_internal_fields.applicable_accessibilities = private, internal +dotnet_naming_style.camel_case_underscore_style.required_prefix = _ +dotnet_naming_style.camel_case_underscore_style.capitalization = camel_case +# Locals and parameters are camelCase +dotnet_naming_rule.locals_should_be_camel_case.severity = error +dotnet_naming_rule.locals_should_be_camel_case.symbols = locals_and_parameters +dotnet_naming_rule.locals_should_be_camel_case.style = camel_case_style +dotnet_naming_symbols.locals_and_parameters.applicable_kinds = parameter, local +dotnet_naming_style.camel_case_style.capitalization = camel_case +# Local functions are PascalCase +dotnet_naming_rule.local_functions_should_be_pascal_case.severity = error +dotnet_naming_rule.local_functions_should_be_pascal_case.symbols = local_functions +dotnet_naming_rule.local_functions_should_be_pascal_case.style = non_private_static_field_style +dotnet_naming_symbols.local_functions.applicable_kinds = local_function +dotnet_naming_style.local_function_style.capitalization = pascal_case +# Type Parameters +dotnet_naming_style.type_parameter_style.capitalization = pascal_case +dotnet_naming_style.type_parameter_style.required_prefix = T +dotnet_naming_rule.type_parameter_naming.symbols = type_parameter_symbol +dotnet_naming_rule.type_parameter_naming.style = type_parameter_style +dotnet_naming_rule.type_parameter_naming.severity = error +dotnet_naming_symbols.type_parameter_symbol.applicable_kinds = type_parameter +dotnet_naming_symbols.type_parameter_symbol.applicable_accessibilities = * +# By default, name items with PascalCase +dotnet_naming_rule.members_should_be_pascal_case.severity = error +dotnet_naming_rule.members_should_be_pascal_case.symbols = all_members +dotnet_naming_rule.members_should_be_pascal_case.style = non_private_static_field_style +dotnet_naming_symbols.all_members.applicable_kinds = * +dotnet_naming_style.pascal_case_style.capitalization = pascal_case +dotnet_style_operator_placement_when_wrapping = beginning_of_line +tab_width = 2 +end_of_line = crlf +dotnet_style_prefer_simplified_boolean_expressions = true:suggestion +dotnet_style_prefer_compound_assignment = true:warning +dotnet_style_prefer_simplified_interpolation = true:warning +dotnet_style_namespace_match_folder = true:suggestion +dotnet_style_allow_multiple_blank_lines_experimental = true:silent +dotnet_style_allow_statement_immediately_after_block_experimental = true:silent +dotnet_code_quality_unused_parameters = non_public:warning ############################### # C# Coding Conventions # ############################### [*.cs] # var preferences -csharp_style_var_for_built_in_types = true:silent -csharp_style_var_when_type_is_apparent = true:silent -csharp_style_var_elsewhere = true:silent +csharp_style_var_for_built_in_types = true:warning +csharp_style_var_when_type_is_apparent = true:warning +csharp_style_var_elsewhere = true:suggestion # Expression-bodied members csharp_style_expression_bodied_methods = false:silent csharp_style_expression_bodied_constructors = false:silent @@ -87,7 +160,7 @@ csharp_prefer_braces = true:silent csharp_style_deconstructed_variable_declaration = true:suggestion csharp_prefer_simple_default_expression = true:suggestion csharp_style_pattern_local_over_anonymous_function = true:suggestion -csharp_style_inlined_variable_declaration = true:suggestion +csharp_style_inlined_variable_declaration = true:warning ############################### # C# Formatting Rules # ############################### @@ -118,9 +191,28 @@ csharp_space_between_method_call_empty_parameter_list_parentheses = false # Wrapping preferences csharp_preserve_single_line_statements = true csharp_preserve_single_line_blocks = true -############################### -# VB Coding Conventions # -############################### -[*.vb] -# Modifier preferences -visual_basic_preferred_modifier_order = Partial,Default,Private,Protected,Public,Friend,NotOverridable,Overridable,MustOverride,Overloads,Overrides,MustInherit,NotInheritable,Static,Shared,Shadows,ReadOnly,WriteOnly,Dim,Const,WithEvents,Widening,Narrowing,Custom,Async:suggestion +csharp_using_directive_placement = outside_namespace:warning +csharp_style_namespace_declarations = file_scoped:warning +csharp_prefer_simple_using_statement = true:silent +csharp_style_expression_bodied_lambdas = true:silent +csharp_style_expression_bodied_local_functions = false:silent +csharp_style_prefer_null_check_over_type_check = true:suggestion +csharp_style_prefer_local_over_anonymous_function = true:suggestion +csharp_style_prefer_index_operator = true:suggestion +csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion +csharp_style_prefer_range_operator = true:suggestion +csharp_style_prefer_tuple_swap = true:suggestion +csharp_style_unused_value_assignment_preference = discard_variable:warning +csharp_style_unused_value_expression_statement_preference = discard_variable:silent +csharp_prefer_static_local_function = true:suggestion +csharp_style_allow_embedded_statements_on_same_line_experimental = true:silent +csharp_style_allow_blank_lines_between_consecutive_braces_experimental = true:silent +csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true:silent +csharp_style_prefer_switch_expression = true:suggestion +csharp_style_prefer_pattern_matching = true:silent +csharp_style_prefer_not_pattern = true:suggestion +csharp_style_prefer_extended_property_pattern = true:suggestion +csharp_style_prefer_method_group_conversion = true:silent +csharp_style_prefer_parameter_null_checking = true:suggestion +csharp_style_prefer_top_level_statements = true:silent +csharp_style_prefer_primary_constructors = true:suggestion diff --git a/.github/workflows/build-test-ef6.yml b/.github/workflows/build-test-ef6.yml index 053f6a95..c985e634 100644 --- a/.github/workflows/build-test-ef6.yml +++ b/.github/workflows/build-test-ef6.yml @@ -24,7 +24,7 @@ jobs: - name: Setup dotnet uses: actions/setup-dotnet@v1 with: - dotnet-version: 6.0.x + dotnet-version: 7.0.x - name: Setup MSBuild.exe uses: microsoft/setup-msbuild@v1.0.2 - name: Build with dotnet diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index fb5920b5..260fa202 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -25,8 +25,8 @@ jobs: - name: Setup dotnet uses: actions/setup-dotnet@v1 with: - dotnet-version: 6.0.x - - name: Build with dotnet 6 + dotnet-version: 7.0.x + - name: Build with dotnet 7 run: | dotnet build Specification/src/Ardalis.Specification/Ardalis.Specification.csproj --configuration Release dotnet build Specification/tests/Ardalis.Specification.UnitTests/Ardalis.Specification.UnitTests.csproj --configuration Release diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 9af6b4e0..e956c3ab 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -17,7 +17,7 @@ jobs: - name: Setup dotnet uses: actions/setup-dotnet@v1 with: - dotnet-version: 6.0.x + dotnet-version: 7.0.x # Publish - name: publish on version change diff --git a/.github/workflows/publishef6.yml b/.github/workflows/publishef6.yml index 907d83b8..d7cc7fcd 100644 --- a/.github/workflows/publishef6.yml +++ b/.github/workflows/publishef6.yml @@ -17,7 +17,7 @@ jobs: - name: Setup dotnet uses: actions/setup-dotnet@v1 with: - dotnet-version: 6.0.x + dotnet-version: 7.0.x - name: Setup MSBuild.exe uses: microsoft/setup-msbuild@v1.0.2 diff --git a/.github/workflows/publishefcore.yml b/.github/workflows/publishefcore.yml index 7d5d394e..1c38e166 100644 --- a/.github/workflows/publishefcore.yml +++ b/.github/workflows/publishefcore.yml @@ -17,7 +17,7 @@ jobs: - name: Setup dotnet uses: actions/setup-dotnet@v1 with: - dotnet-version: 6.0.x + dotnet-version: 7.0.x # Publish - name: publish on version change diff --git a/Ardalis.Specification.sln b/Ardalis.Specification.sln index 96d0d522..c70637d7 100644 --- a/Ardalis.Specification.sln +++ b/Ardalis.Specification.sln @@ -29,6 +29,7 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "_Solution Items", "_Solution Items", "{C443291A-7311-455F-9AC6-995EB29DD6D2}" ProjectSection(SolutionItems) = preProject .editorconfig = .editorconfig + .gitignore = .gitignore README.md = README.md EndProjectSection EndProject @@ -44,8 +45,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Specification.EntityFramewo EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Specification.EntityFramework6", "Specification.EntityFramework6", "{327AEBD6-C8A6-4851-BA42-632F8014CFC5}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ardalis.Specification.EntityFrameworkCore.UnitTests", "Specification.EntityFrameworkCore\tests\Ardalis.Specification.EntityFrameworkCore.UnitTests\Ardalis.Specification.EntityFrameworkCore.UnitTests.csproj", "{53E4FFB4-CAC0-482D-B714-FA657C3244C9}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -88,10 +87,6 @@ Global {4BEB4DC4-DE33-4DF1-8A2F-CE76C1D72A4A}.Debug|Any CPU.Build.0 = Debug|Any CPU {4BEB4DC4-DE33-4DF1-8A2F-CE76C1D72A4A}.Release|Any CPU.ActiveCfg = Release|Any CPU {4BEB4DC4-DE33-4DF1-8A2F-CE76C1D72A4A}.Release|Any CPU.Build.0 = Release|Any CPU - {53E4FFB4-CAC0-482D-B714-FA657C3244C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {53E4FFB4-CAC0-482D-B714-FA657C3244C9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {53E4FFB4-CAC0-482D-B714-FA657C3244C9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {53E4FFB4-CAC0-482D-B714-FA657C3244C9}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -106,7 +101,6 @@ Global {5AFD1454-E625-451D-A615-CEB7BB09AA65} = {B19F2F64-4B22-48C2-B2F8-7672F84F758D} {37EC09C7-702D-4539-B98D-F67B15E1E6CE} = {327AEBD6-C8A6-4851-BA42-632F8014CFC5} {4BEB4DC4-DE33-4DF1-8A2F-CE76C1D72A4A} = {327AEBD6-C8A6-4851-BA42-632F8014CFC5} - {53E4FFB4-CAC0-482D-B714-FA657C3244C9} = {B19F2F64-4B22-48C2-B2F8-7672F84F758D} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {C153A625-42F7-49A7-B99A-6A78B4B866B2} diff --git a/Dockerfile b/Dockerfile index 31687362..9587d62b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build +FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build WORKDIR / COPY . ./ @@ -7,6 +7,6 @@ ADD https://github.com/ufoscout/docker-compose-wait/releases/download/2.8.0/wait RUN /bin/bash -c 'ls -la /wait; chmod +x /wait; ls -la /wait' # install the report generator tool -RUN dotnet tool install dotnet-reportgenerator-globaltool --version 4.8.7 --tool-path /tools +RUN dotnet tool install dotnet-reportgenerator-globaltool --version 5.1.23 --tool-path /tools -CMD /wait && dotnet test -f net6.0 Specification/tests/Ardalis.Specification.UnitTests/Ardalis.Specification.UnitTests.csproj --logger trx --results-directory /var/temp /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura && mv /Specification/tests/Ardalis.Specification.UnitTests/coverage.net6.0.cobertura.xml /var/temp/coverage.unit.cobertura.xml && dotnet test Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests.csproj --logger trx --results-directory /var/temp /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura && mv /Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/coverage.cobertura.xml /var/temp/coverage.ef.integration.cobertura.xml && tools/reportgenerator -reports:/var/temp/coverage.*.cobertura.xml -targetdir:/var/temp/coverage -reporttypes:HtmlInline_AzurePipelines\;HTMLChart\;Cobertura \ No newline at end of file +CMD /wait && dotnet test -f net7.0 Specification/tests/Ardalis.Specification.UnitTests/Ardalis.Specification.UnitTests.csproj --collect:"XPlat Code Coverage" && dotnet test -f net7.0 Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests.csproj --collect:"XPlat Code Coverage" && tools/reportgenerator -reports:Specification*/**/coverage.cobertura.xml -targetdir:/var/temp/coverage -reporttypes:HtmlInline_AzurePipelines\;HTMLChart\;Cobertura diff --git a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Ardalis.Specification.EntityFramework6.csproj b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Ardalis.Specification.EntityFramework6.csproj index 18c7d61b..6333bf0a 100644 --- a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Ardalis.Specification.EntityFramework6.csproj +++ b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Ardalis.Specification.EntityFramework6.csproj @@ -2,33 +2,36 @@ net472 + 11.0 Library false + + Ardalis.Specification.EntityFramework6 Ardalis.Specification.EntityFramework6 Ardalis.Specification.EntityFramework6 true Steve Smith (@ardalis); Fati Iseni (@fiseni); Scott DePouw Ardalis.com - https://github.com/ardalis/specification EF6 plugin package to Ardalis.Specification containing EF6 evaluator and abstract repository. EF6 plugin package to Ardalis.Specification containing EF6 evaluator and abstract repository. + https://github.com/ardalis/specification https://github.com/ardalis/specification spec;specification;repository;ddd;ef;ef6;entity framework + icon.png 7.0.0 - * Patch 2 by @davidhenley in https://github.com/ardalis/Specification/pull/283 - * Fix `Just the Docs` link in docs home page by @snowfrogdev in https://github.com/ardalis/Specification/pull/293 - * Update url path by @ta1H3n in https://github.com/ardalis/Specification/pull/303 - * Implement SelectMany support by @amdavie in https://github.com/ardalis/Specification/pull/320 - * Add two methods for consuming repositories in scenarios where repositories could be longer lived (e.g. Blazor component Injections) by @jasonsummers in https://github.com/ardalis/Specification/pull/289 - * Added support for AsAsyncEnumerable by @nkz-soft in https://github.com/ardalis/Specification/pull/316 - * Lamadelrae/doc faq ef versions by @Lamadelrae in https://github.com/ardalis/Specification/pull/324 - * Updated projects, drop support for old TFMs. by @fiseni in https://github.com/ardalis/Specification/pull/326 - * Update the search feature to generate parameterized query. by @fiseni in https://github.com/ardalis/Specification/pull/327 - * Add support for extending default evaluator list by @fiseni in https://github.com/ardalis/Specification/pull/328 - * Ardalis/cleanup by @ardalis in https://github.com/ardalis/Specification/pull/332 - Ardalis.Specification.EntityFramework6 - icon.png + * Patch 2 by @davidhenley in https://github.com/ardalis/Specification/pull/283 + * Fix `Just the Docs` link in docs home page by @snowfrogdev in https://github.com/ardalis/Specification/pull/293 + * Update url path by @ta1H3n in https://github.com/ardalis/Specification/pull/303 + * Implement SelectMany support by @amdavie in https://github.com/ardalis/Specification/pull/320 + * Add two methods for consuming repositories in scenarios where repositories could be longer lived (e.g. Blazor component Injections) by @jasonsummers in https://github.com/ardalis/Specification/pull/289 + * Added support for AsAsyncEnumerable by @nkz-soft in https://github.com/ardalis/Specification/pull/316 + * Lamadelrae/doc faq ef versions by @Lamadelrae in https://github.com/ardalis/Specification/pull/324 + * Updated projects, drop support for old TFMs. by @fiseni in https://github.com/ardalis/Specification/pull/326 + * Update the search feature to generate parameterized query. by @fiseni in https://github.com/ardalis/Specification/pull/327 + * Add support for extending default evaluator list by @fiseni in https://github.com/ardalis/Specification/pull/328 + * Ardalis/cleanup by @ardalis in https://github.com/ardalis/Specification/pull/332 + true true $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb @@ -40,13 +43,16 @@ - + - + - + + + 1701;1702;1591;1573;1712 + diff --git a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Evaluators/AsNoTrackingEvaluator.cs b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Evaluators/AsNoTrackingEvaluator.cs index ffccb719..7c9fdaf9 100644 --- a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Evaluators/AsNoTrackingEvaluator.cs +++ b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Evaluators/AsNoTrackingEvaluator.cs @@ -1,23 +1,22 @@ using System.Data.Entity; using System.Linq; -namespace Ardalis.Specification.EntityFramework6 +namespace Ardalis.Specification.EntityFramework6; + +public class AsNoTrackingEvaluator : IEvaluator { - public class AsNoTrackingEvaluator : IEvaluator - { - private AsNoTrackingEvaluator() { } - public static AsNoTrackingEvaluator Instance { get; } = new AsNoTrackingEvaluator(); + private AsNoTrackingEvaluator() { } + public static AsNoTrackingEvaluator Instance { get; } = new AsNoTrackingEvaluator(); - public bool IsCriteriaEvaluator { get; } = true; + public bool IsCriteriaEvaluator { get; } = true; - public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class + public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class + { + if (specification.AsNoTracking) { - if (specification.AsNoTracking) - { - query = query.AsNoTracking(); - } - - return query; + query = query.AsNoTracking(); } + + return query; } } diff --git a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Evaluators/IncludeEvaluator.cs b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Evaluators/IncludeEvaluator.cs index 50734215..61f7a237 100644 --- a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Evaluators/IncludeEvaluator.cs +++ b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Evaluators/IncludeEvaluator.cs @@ -1,35 +1,34 @@ using System.Data.Entity; using System.Linq; -namespace Ardalis.Specification.EntityFramework6 +namespace Ardalis.Specification.EntityFramework6; + +public class IncludeEvaluator : IEvaluator { - public class IncludeEvaluator : IEvaluator - { - private IncludeEvaluator() { } - public static IncludeEvaluator Instance { get; } = new IncludeEvaluator(); + private IncludeEvaluator() { } + public static IncludeEvaluator Instance { get; } = new IncludeEvaluator(); - public bool IsCriteriaEvaluator { get; } = false; + public bool IsCriteriaEvaluator { get; } = false; - public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class + public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class + { + foreach (var includeString in specification.IncludeStrings) { - foreach (var includeString in specification.IncludeStrings) + query = query.Include(includeString); + } + + foreach (var includeInfo in specification.IncludeExpressions) + { + if (includeInfo.Type == IncludeTypeEnum.Include) { - query = query.Include(includeString); + query = query.Include(includeInfo); } - - foreach (var includeInfo in specification.IncludeExpressions) + else if (includeInfo.Type == IncludeTypeEnum.ThenInclude) { - if (includeInfo.Type == IncludeTypeEnum.Include) - { - query = query.Include(includeInfo); - } - else if (includeInfo.Type == IncludeTypeEnum.ThenInclude) - { - query = query.ThenInclude(includeInfo); - } + query = query.ThenInclude(includeInfo); } - - return query; } + + return query; } } diff --git a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Evaluators/OrderEvaluator.cs b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Evaluators/OrderEvaluator.cs index 5f4a328e..12721da4 100644 --- a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Evaluators/OrderEvaluator.cs +++ b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Evaluators/OrderEvaluator.cs @@ -2,102 +2,101 @@ using System.Linq; using System.Linq.Expressions; -namespace Ardalis.Specification.EntityFramework6 +namespace Ardalis.Specification.EntityFramework6; + +public class OrderEvaluator : IEvaluator, IInMemoryEvaluator { - public class OrderEvaluator : IEvaluator, IInMemoryEvaluator - { - private OrderEvaluator() { } - public static OrderEvaluator Instance { get; } = new OrderEvaluator(); + private OrderEvaluator() { } + public static OrderEvaluator Instance { get; } = new OrderEvaluator(); - public bool IsCriteriaEvaluator { get; } = false; + public bool IsCriteriaEvaluator { get; } = false; - public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class + public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class + { + if (specification.OrderExpressions != null) { - if (specification.OrderExpressions != null) + if (specification.OrderExpressions.Count(x => x.OrderType == OrderTypeEnum.OrderBy + || x.OrderType == OrderTypeEnum.OrderByDescending) > 1) + { + throw new DuplicateOrderChainException(); + } + + IOrderedQueryable orderedQuery = null; + foreach (var orderExpression in specification.OrderExpressions) { - if (specification.OrderExpressions.Count(x => x.OrderType == OrderTypeEnum.OrderBy - || x.OrderType == OrderTypeEnum.OrderByDescending) > 1) + if (orderExpression.OrderType == OrderTypeEnum.OrderBy) { - throw new DuplicateOrderChainException(); + orderedQuery = Queryable.OrderBy((dynamic)query, (dynamic)RemoveConvert(orderExpression.KeySelector)); } - - IOrderedQueryable orderedQuery = null; - foreach (var orderExpression in specification.OrderExpressions) + else if (orderExpression.OrderType == OrderTypeEnum.OrderByDescending) { - if (orderExpression.OrderType == OrderTypeEnum.OrderBy) - { - orderedQuery = Queryable.OrderBy((dynamic)query, (dynamic)RemoveConvert(orderExpression.KeySelector)); - } - else if (orderExpression.OrderType == OrderTypeEnum.OrderByDescending) - { - orderedQuery = Queryable.OrderByDescending((dynamic)query, (dynamic)RemoveConvert(orderExpression.KeySelector)); - } - else if (orderExpression.OrderType == OrderTypeEnum.ThenBy) - { - orderedQuery = Queryable.ThenBy((dynamic)orderedQuery, (dynamic)RemoveConvert(orderExpression.KeySelector)); - } - else if (orderExpression.OrderType == OrderTypeEnum.ThenByDescending) - { - orderedQuery = Queryable.ThenByDescending((dynamic)orderedQuery, (dynamic)RemoveConvert(orderExpression.KeySelector)); - } + orderedQuery = Queryable.OrderByDescending((dynamic)query, (dynamic)RemoveConvert(orderExpression.KeySelector)); } - - if (orderedQuery != null) + else if (orderExpression.OrderType == OrderTypeEnum.ThenBy) { - query = orderedQuery; + orderedQuery = Queryable.ThenBy((dynamic)orderedQuery, (dynamic)RemoveConvert(orderExpression.KeySelector)); + } + else if (orderExpression.OrderType == OrderTypeEnum.ThenByDescending) + { + orderedQuery = Queryable.ThenByDescending((dynamic)orderedQuery, (dynamic)RemoveConvert(orderExpression.KeySelector)); } } - return query; + if (orderedQuery != null) + { + query = orderedQuery; + } } - public IEnumerable Evaluate(IEnumerable query, ISpecification specification) + return query; + } + + public IEnumerable Evaluate(IEnumerable query, ISpecification specification) + { + if (specification.OrderExpressions != null) { - if (specification.OrderExpressions != null) + if (specification.OrderExpressions.Count(x => x.OrderType == OrderTypeEnum.OrderBy + || x.OrderType == OrderTypeEnum.OrderByDescending) > 1) { - if (specification.OrderExpressions.Count(x => x.OrderType == OrderTypeEnum.OrderBy - || x.OrderType == OrderTypeEnum.OrderByDescending) > 1) + throw new DuplicateOrderChainException(); + } + + IOrderedEnumerable orderedQuery = null; + foreach (var orderExpression in specification.OrderExpressions) + { + if (orderExpression.OrderType == OrderTypeEnum.OrderBy) { - throw new DuplicateOrderChainException(); + orderedQuery = Queryable.OrderBy((dynamic)query, (dynamic)RemoveConvert(orderExpression.KeySelector)); } - - IOrderedEnumerable orderedQuery = null; - foreach (var orderExpression in specification.OrderExpressions) + else if (orderExpression.OrderType == OrderTypeEnum.OrderByDescending) { - if (orderExpression.OrderType == OrderTypeEnum.OrderBy) - { - orderedQuery = Queryable.OrderBy((dynamic)query, (dynamic)RemoveConvert(orderExpression.KeySelector)); - } - else if (orderExpression.OrderType == OrderTypeEnum.OrderByDescending) - { - orderedQuery = Queryable.OrderByDescending((dynamic)query, (dynamic)RemoveConvert(orderExpression.KeySelector)); - } - else if (orderExpression.OrderType == OrderTypeEnum.ThenBy) - { - orderedQuery = Queryable.ThenBy((dynamic)orderedQuery, (dynamic)RemoveConvert(orderExpression.KeySelector)); - } - else if (orderExpression.OrderType == OrderTypeEnum.ThenByDescending) - { - orderedQuery = Queryable.ThenByDescending((dynamic)orderedQuery, (dynamic)RemoveConvert(orderExpression.KeySelector)); - } + orderedQuery = Queryable.OrderByDescending((dynamic)query, (dynamic)RemoveConvert(orderExpression.KeySelector)); } - - if (orderedQuery != null) + else if (orderExpression.OrderType == OrderTypeEnum.ThenBy) + { + orderedQuery = Queryable.ThenBy((dynamic)orderedQuery, (dynamic)RemoveConvert(orderExpression.KeySelector)); + } + else if (orderExpression.OrderType == OrderTypeEnum.ThenByDescending) { - query = orderedQuery; + orderedQuery = Queryable.ThenByDescending((dynamic)orderedQuery, (dynamic)RemoveConvert(orderExpression.KeySelector)); } } - return query; + if (orderedQuery != null) + { + query = orderedQuery; + } } - private LambdaExpression RemoveConvert(LambdaExpression source) - { - var body = source.Body; - while (body.NodeType == ExpressionType.Convert) - body = ((UnaryExpression)body).Operand; + return query; + } - return Expression.Lambda(body, source.Parameters); - } + private LambdaExpression RemoveConvert(LambdaExpression source) + { + var body = source.Body; + while (body.NodeType == ExpressionType.Convert) + body = ((UnaryExpression)body).Operand; + + return Expression.Lambda(body, source.Parameters); } } diff --git a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Evaluators/SearchEvaluator.cs b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Evaluators/SearchEvaluator.cs index 67d8ddda..91279d04 100644 --- a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Evaluators/SearchEvaluator.cs +++ b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Evaluators/SearchEvaluator.cs @@ -1,22 +1,21 @@ using System.Linq; -namespace Ardalis.Specification.EntityFramework6 +namespace Ardalis.Specification.EntityFramework6; + +public class SearchEvaluator : IEvaluator { - public class SearchEvaluator : IEvaluator - { - private SearchEvaluator() { } - public static SearchEvaluator Instance { get; } = new SearchEvaluator(); + private SearchEvaluator() { } + public static SearchEvaluator Instance { get; } = new SearchEvaluator(); - public bool IsCriteriaEvaluator { get; } = true; + public bool IsCriteriaEvaluator { get; } = true; - public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class + public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class + { + foreach (var searchCriteria in specification.SearchCriterias.GroupBy(x => x.SearchGroup)) { - foreach (var searchCriteria in specification.SearchCriterias.GroupBy(x => x.SearchGroup)) - { - query = query.Search(searchCriteria); - } - - return query; + query = query.Search(searchCriteria); } + + return query; } } diff --git a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Evaluators/SpecificationEvaluator.cs b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Evaluators/SpecificationEvaluator.cs index 75d9ebf7..1c2c3b63 100644 --- a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Evaluators/SpecificationEvaluator.cs +++ b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Evaluators/SpecificationEvaluator.cs @@ -2,60 +2,59 @@ using System.Collections.Generic; using System.Linq; -namespace Ardalis.Specification.EntityFramework6 +namespace Ardalis.Specification.EntityFramework6; + +/// +public class SpecificationEvaluator : ISpecificationEvaluator { - /// - public class SpecificationEvaluator : ISpecificationEvaluator - { - // Will use singleton for default configuration. Yet, it can be instantiated if necessary, with default or provided evaluators. - public static SpecificationEvaluator Default { get; } = new SpecificationEvaluator(); + // Will use singleton for default configuration. Yet, it can be instantiated if necessary, with default or provided evaluators. + public static SpecificationEvaluator Default { get; } = new SpecificationEvaluator(); - protected List Evaluators { get; } = new List(); + protected List Evaluators { get; } = new List(); - public SpecificationEvaluator() - { - this.Evaluators.AddRange(new IEvaluator[] - { - WhereEvaluator.Instance, - SearchEvaluator.Instance, - IncludeEvaluator.Instance, - OrderEvaluator.Instance, - PaginationEvaluator.Instance, - AsNoTrackingEvaluator.Instance - }); - } - public SpecificationEvaluator(IEnumerable evaluators) - { - this.Evaluators.AddRange(evaluators); - } - - /// - public virtual IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class + public SpecificationEvaluator() + { + Evaluators.AddRange(new IEvaluator[] { - if (specification is null) throw new ArgumentNullException("Specification is required"); - if (specification.Selector is null && specification.SelectorMany is null) throw new SelectorNotFoundException(); - if (specification.Selector != null && specification.SelectorMany != null) throw new ConcurrentSelectorsException(); + WhereEvaluator.Instance, + SearchEvaluator.Instance, + IncludeEvaluator.Instance, + OrderEvaluator.Instance, + PaginationEvaluator.Instance, + AsNoTrackingEvaluator.Instance + }); + } + public SpecificationEvaluator(IEnumerable evaluators) + { + Evaluators.AddRange(evaluators); + } - query = GetQuery(query, (ISpecification)specification); + /// + public virtual IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class + { + if (specification is null) throw new ArgumentNullException("Specification is required"); + if (specification.Selector is null && specification.SelectorMany is null) throw new SelectorNotFoundException(); + if (specification.Selector != null && specification.SelectorMany != null) throw new ConcurrentSelectorsException(); - return specification.Selector != null - ? query.Select(specification.Selector) - : query.SelectMany(specification.SelectorMany); - } + query = GetQuery(query, (ISpecification)specification); - /// - public virtual IQueryable GetQuery(IQueryable query, ISpecification specification, bool evaluateCriteriaOnly = false) where T : class - { - if (specification is null) throw new ArgumentNullException("Specification is required"); + return specification.Selector != null + ? query.Select(specification.Selector) + : query.SelectMany(specification.SelectorMany); + } - var evaluators = evaluateCriteriaOnly ? this.Evaluators.Where(x => x.IsCriteriaEvaluator) : this.Evaluators; + /// + public virtual IQueryable GetQuery(IQueryable query, ISpecification specification, bool evaluateCriteriaOnly = false) where T : class + { + if (specification is null) throw new ArgumentNullException("Specification is required"); - foreach (var evaluator in evaluators) - { - query = evaluator.GetQuery(query, specification); - } + var evaluators = evaluateCriteriaOnly ? Evaluators.Where(x => x.IsCriteriaEvaluator) : Evaluators; - return query; + foreach (var evaluator in evaluators) + { + query = evaluator.GetQuery(query, specification); } + + return query; } } diff --git a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Extensions/DbSetExtensions.cs b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Extensions/DbSetExtensions.cs index 03497123..0494d693 100644 --- a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Extensions/DbSetExtensions.cs +++ b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Extensions/DbSetExtensions.cs @@ -4,54 +4,53 @@ using System.Threading; using System.Threading.Tasks; -namespace Ardalis.Specification.EntityFramework6 +namespace Ardalis.Specification.EntityFramework6; + +public static class DbSetExtensions { - public static class DbSetExtensions + public static async Task> ToListAsync( + this DbSet source, + ISpecification specification, + CancellationToken cancellationToken = default) + where TSource : class { - public static async Task> ToListAsync( - this DbSet source, - ISpecification specification, - CancellationToken cancellationToken = default) - where TSource : class - { - var result = await SpecificationEvaluator.Default.GetQuery(source, specification).ToListAsync(cancellationToken); + var result = await SpecificationEvaluator.Default.GetQuery(source, specification).ToListAsync(cancellationToken); - return specification.PostProcessingAction == null - ? result - : specification.PostProcessingAction(result).ToList(); - } + return specification.PostProcessingAction == null + ? result + : specification.PostProcessingAction(result).ToList(); + } - public static async Task> ToEnumerableAsync( - this DbSet source, - ISpecification specification, - CancellationToken cancellationToken = default) - where TSource : class - { - var result = await SpecificationEvaluator.Default.GetQuery(source, specification).ToListAsync(cancellationToken); + public static async Task> ToEnumerableAsync( + this DbSet source, + ISpecification specification, + CancellationToken cancellationToken = default) + where TSource : class + { + var result = await SpecificationEvaluator.Default.GetQuery(source, specification).ToListAsync(cancellationToken); - return specification.PostProcessingAction == null - ? result - : specification.PostProcessingAction(result); - } + return specification.PostProcessingAction == null + ? result + : specification.PostProcessingAction(result); + } - public static IQueryable WithSpecification( - this IQueryable source, - ISpecification specification, - ISpecificationEvaluator evaluator = null) - where TSource : class - { - evaluator = evaluator ?? SpecificationEvaluator.Default; - return evaluator.GetQuery(source, specification); - } + public static IQueryable WithSpecification( + this IQueryable source, + ISpecification specification, + ISpecificationEvaluator evaluator = null) + where TSource : class + { + evaluator ??= SpecificationEvaluator.Default; + return evaluator.GetQuery(source, specification); + } - public static IQueryable WithSpecification( - this IQueryable source, - ISpecification specification, - ISpecificationEvaluator evaluator = null) - where TSource : class - { - evaluator = evaluator ?? SpecificationEvaluator.Default; - return evaluator.GetQuery(source, specification); - } + public static IQueryable WithSpecification( + this IQueryable source, + ISpecification specification, + ISpecificationEvaluator evaluator = null) + where TSource : class + { + evaluator ??= SpecificationEvaluator.Default; + return evaluator.GetQuery(source, specification); } } diff --git a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Extensions/IncludeExtensions.cs b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Extensions/IncludeExtensions.cs index 0c5bb473..ff39c3a2 100644 --- a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Extensions/IncludeExtensions.cs +++ b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Extensions/IncludeExtensions.cs @@ -5,61 +5,60 @@ using System.Linq.Expressions; using System.Reflection; -namespace Ardalis.Specification.EntityFramework6 +namespace Ardalis.Specification.EntityFramework6; + +public static class IncludeExtensions { - public static class IncludeExtensions + public static IQueryable Include(this IQueryable source, IncludeExpressionInfo info) { - public static IQueryable Include(this IQueryable source, IncludeExpressionInfo info) - { - _ = info ?? throw new ArgumentNullException(nameof(info)); - var propertyName = GetPropertyName(info.LambdaExpression); + _ = info ?? throw new ArgumentNullException(nameof(info)); + var propertyName = GetPropertyName(info.LambdaExpression); - return QueryableExtensions.Include(source, propertyName); - } + return QueryableExtensions.Include(source, propertyName); + } - public static IQueryable ThenInclude(this IQueryable source, IncludeExpressionInfo info) - { - _ = info ?? throw new ArgumentNullException(nameof(info)); - _ = info.PreviousPropertyType ?? throw new ArgumentNullException(nameof(info.PreviousPropertyType)); + public static IQueryable ThenInclude(this IQueryable source, IncludeExpressionInfo info) + { + _ = info ?? throw new ArgumentNullException(nameof(info)); + _ = info.PreviousPropertyType ?? throw new ArgumentNullException(nameof(info.PreviousPropertyType)); - var exp = source.Expression as MethodCallExpression; - var arg = exp.Arguments[0] as ConstantExpression; + var exp = source.Expression as MethodCallExpression; + var arg = exp.Arguments[0] as ConstantExpression; - string previousPropertyName; - if (arg.Value is string) - { - previousPropertyName = arg.Value.ToString(); - } - else - { - // System.Data.Entity.Core.Objects.Span is an internal class, so here's some reflection to get to the previous property. + string previousPropertyName; + if (arg.Value is string) + { + previousPropertyName = arg.Value.ToString(); + } + else + { + // System.Data.Entity.Core.Objects.Span is an internal class, so here's some reflection to get to the previous property. - var propertyInfo = arg.Value.GetType().GetProperty("SpanList", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); - var spanList = propertyInfo.GetValue(arg.Value); + var propertyInfo = arg.Value.GetType().GetProperty("SpanList", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + var spanList = propertyInfo.GetValue(arg.Value); - // Get the first item of the span list - propertyInfo = propertyInfo.PropertyType.GetProperty("Item"); - var spanPath = propertyInfo.GetValue(spanList, new object[] { 0 }); + // Get the first item of the span list + propertyInfo = propertyInfo.PropertyType.GetProperty("Item"); + var spanPath = propertyInfo.GetValue(spanList, new object[] { 0 }); - var fieldInfo = spanPath.GetType().GetField("Navigations", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); - var navigations = fieldInfo.GetValue(spanPath) as List; - previousPropertyName = string.Join(".", navigations); - } + var fieldInfo = spanPath.GetType().GetField("Navigations", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + var navigations = fieldInfo.GetValue(spanPath) as List; + previousPropertyName = string.Join(".", navigations); + } - var propertyName = GetPropertyName(info.LambdaExpression); + var propertyName = GetPropertyName(info.LambdaExpression); - return QueryableExtensions.Include(source, $"{previousPropertyName}.{propertyName}"); - } + return QueryableExtensions.Include(source, $"{previousPropertyName}.{propertyName}"); + } - private static string GetPropertyName(this Expression propertySelector, char delimiter = '.', char endTrim = ')') - { + private static string GetPropertyName(this Expression propertySelector, char delimiter = '.', char endTrim = ')') + { - var asString = propertySelector.ToString(); - var firstDelim = asString.IndexOf(delimiter); + var asString = propertySelector.ToString(); + var firstDelim = asString.IndexOf(delimiter); - return firstDelim < 0 - ? asString - : asString.Substring(firstDelim + 1).TrimEnd(endTrim); - } + return firstDelim < 0 + ? asString + : asString.Substring(firstDelim + 1).TrimEnd(endTrim); } } diff --git a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Extensions/ParameterReplacerVisitor.cs b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Extensions/ParameterReplacerVisitor.cs index 942d25f1..15020078 100644 --- a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Extensions/ParameterReplacerVisitor.cs +++ b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Extensions/ParameterReplacerVisitor.cs @@ -1,33 +1,21 @@ using System.Linq.Expressions; -namespace Ardalis.Specification.EntityFramework6 +namespace Ardalis.Specification.EntityFramework6; + +internal class ParameterReplacerVisitor : ExpressionVisitor { - internal class ParameterReplacerVisitor : ExpressionVisitor - { - private readonly Expression newExpression; - private readonly ParameterExpression oldParameter; + private readonly Expression _newExpression; + private readonly ParameterExpression _oldParameter; - private ParameterReplacerVisitor(ParameterExpression oldParameter, Expression newExpression) - { - this.oldParameter = oldParameter; - this.newExpression = newExpression; - } + private ParameterReplacerVisitor(ParameterExpression oldParameter, Expression newExpression) + { + _oldParameter = oldParameter; + _newExpression = newExpression; + } - internal static Expression Replace(Expression expression, ParameterExpression oldParameter, Expression newExpression) - { - return new ParameterReplacerVisitor(oldParameter, newExpression).Visit(expression); - } + internal static Expression Replace(Expression expression, ParameterExpression oldParameter, Expression newExpression) + => new ParameterReplacerVisitor(oldParameter, newExpression).Visit(expression); - protected override Expression VisitParameter(ParameterExpression p) - { - if (p == oldParameter) - { - return newExpression; - } - else - { - return p; - } - } - } + protected override Expression VisitParameter(ParameterExpression p) + => p == _oldParameter ? _newExpression : p; } diff --git a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Extensions/SearchExtension.cs b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Extensions/SearchExtension.cs index 8cffe870..9061ed81 100644 --- a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Extensions/SearchExtension.cs +++ b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Extensions/SearchExtension.cs @@ -4,51 +4,50 @@ using System.Linq; using System.Linq.Expressions; -namespace Ardalis.Specification.EntityFramework6 +namespace Ardalis.Specification.EntityFramework6; + +public static class SearchExtension { - public static class SearchExtension + /// + /// Filters by applying an 'SQL LIKE' operation to it. + /// + /// The type being queried against. + /// The sequence of + /// + /// + /// Selector, the property to apply the SQL LIKE against. + /// SearchTerm, the value to use for the SQL LIKE. + /// + /// + /// + public static IQueryable Search(this IQueryable source, IEnumerable> criterias) { - /// - /// Filters by applying an 'SQL LIKE' operation to it. - /// - /// The type being queried against. - /// The sequence of - /// - /// - /// Selector, the property to apply the SQL LIKE against. - /// SearchTerm, the value to use for the SQL LIKE. - /// - /// - /// - public static IQueryable Search(this IQueryable source, IEnumerable> criterias) - { - Expression expr = null; - var parameter = Expression.Parameter(typeof(T), "x"); + Expression expr = null; + var parameter = Expression.Parameter(typeof(T), "x"); - foreach (var criteria in criterias) + foreach (var criteria in criterias) + { + var (selector, searchTerm) = (criteria.Selector, criteria.SearchTerm); + if (string.IsNullOrEmpty(criteria.SearchTerm)) { - var (selector, searchTerm) = (criteria.Selector, criteria.SearchTerm); - if (string.IsNullOrEmpty(criteria.SearchTerm)) - { - continue; - } - - var like = typeof(DbFunctions).GetMethod(nameof(DbFunctions.Like), new Type[] { typeof(string), typeof(string) }); + continue; + } - var propertySelector = ParameterReplacerVisitor.Replace(selector, selector.Parameters[0], parameter); + var like = typeof(DbFunctions).GetMethod(nameof(DbFunctions.Like), new Type[] { typeof(string), typeof(string) }); - var likeExpression = Expression.Call( - null, - like, - (propertySelector as LambdaExpression)?.Body, - Expression.Constant(searchTerm)); + var propertySelector = ParameterReplacerVisitor.Replace(selector, selector.Parameters[0], parameter); - expr = expr == null ? (Expression)likeExpression : Expression.OrElse(expr, likeExpression); - } + var likeExpression = Expression.Call( + null, + like, + (propertySelector as LambdaExpression)?.Body, + Expression.Constant(searchTerm)); - return expr == null - ? source - : source.Where(Expression.Lambda>(expr, parameter)); + expr = expr == null ? (Expression)likeExpression : Expression.OrElse(expr, likeExpression); } + + return expr == null + ? source + : source.Where(Expression.Lambda>(expr, parameter)); } } diff --git a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Properties/AssemblyInfo.cs b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Properties/AssemblyInfo.cs index 01386a11..481099a7 100644 --- a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Properties/AssemblyInfo.cs +++ b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following diff --git a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/RepositoryBaseOfT.cs b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/RepositoryBaseOfT.cs index ed50d851..512280c1 100644 --- a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/RepositoryBaseOfT.cs +++ b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/RepositoryBaseOfT.cs @@ -5,201 +5,200 @@ using System.Threading; using System.Threading.Tasks; -namespace Ardalis.Specification.EntityFramework6 +namespace Ardalis.Specification.EntityFramework6; + +/// +public abstract class RepositoryBase : IRepositoryBase where T : class { + private readonly DbContext _dbContext; + private readonly ISpecificationEvaluator _specificationEvaluator; + + public RepositoryBase(DbContext dbContext) + : this(dbContext, SpecificationEvaluator.Default) + { + } + /// - public abstract class RepositoryBase : IRepositoryBase where T : class + public RepositoryBase(DbContext dbContext, ISpecificationEvaluator specificationEvaluator) { - private readonly DbContext dbContext; - private readonly ISpecificationEvaluator specificationEvaluator; + _dbContext = dbContext; + _specificationEvaluator = specificationEvaluator; + } - public RepositoryBase(DbContext dbContext) - : this(dbContext, SpecificationEvaluator.Default) - { - } + /// + public virtual async Task AddAsync(T entity, CancellationToken cancellationToken = default) + { + _dbContext.Set().Add(entity); - /// - public RepositoryBase(DbContext dbContext, ISpecificationEvaluator specificationEvaluator) - { - this.dbContext = dbContext; - this.specificationEvaluator = specificationEvaluator; - } + await SaveChangesAsync(cancellationToken); - /// - public virtual async Task AddAsync(T entity, CancellationToken cancellationToken = default) - { - dbContext.Set().Add(entity); + return entity; + } - await SaveChangesAsync(cancellationToken); + /// + public virtual async Task> AddRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) + { + _dbContext.Set().AddRange(entities); - return entity; - } + await SaveChangesAsync(cancellationToken); - /// - public virtual async Task> AddRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) - { - dbContext.Set().AddRange(entities); + return entities; + } - await SaveChangesAsync(cancellationToken); + /// + public virtual async Task UpdateAsync(T entity, CancellationToken cancellationToken = default) + { + _dbContext.Entry(entity).State = EntityState.Modified; - return entities; - } - - /// - public virtual async Task UpdateAsync(T entity, CancellationToken cancellationToken = default) - { - dbContext.Entry(entity).State = EntityState.Modified; + await SaveChangesAsync(cancellationToken); + } - await SaveChangesAsync(cancellationToken); + /// + public virtual async Task UpdateRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) + { + foreach (var entity in entities) + { + _dbContext.Entry(entity).State = EntityState.Modified; } - /// - public virtual async Task UpdateRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) - { - foreach (var entity in entities) - { - dbContext.Entry(entity).State = EntityState.Modified; - } + await SaveChangesAsync(cancellationToken); + } - await SaveChangesAsync(cancellationToken); - } + /// + public virtual async Task DeleteAsync(T entity, CancellationToken cancellationToken = default) + { + _dbContext.Set().Remove(entity); - /// - public virtual async Task DeleteAsync(T entity, CancellationToken cancellationToken = default) - { - dbContext.Set().Remove(entity); + await SaveChangesAsync(cancellationToken); + } - await SaveChangesAsync(cancellationToken); - } + /// + public virtual async Task DeleteRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) + { + _dbContext.Set().RemoveRange(entities); - /// - public virtual async Task DeleteRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) - { - dbContext.Set().RemoveRange(entities); + await SaveChangesAsync(cancellationToken); + } - await SaveChangesAsync(cancellationToken); - } - - /// - public virtual async Task SaveChangesAsync(CancellationToken cancellationToken = default) - { - return await dbContext.SaveChangesAsync(cancellationToken); - } + /// + public virtual async Task SaveChangesAsync(CancellationToken cancellationToken = default) + { + return await _dbContext.SaveChangesAsync(cancellationToken); + } - /// - public virtual async Task GetByIdAsync(TId id, CancellationToken cancellationToken = default) - { - return await dbContext.Set().FindAsync(cancellationToken: cancellationToken, new object[] { id }); - } + /// + public virtual async Task GetByIdAsync(TId id, CancellationToken cancellationToken = default) + { + return await _dbContext.Set().FindAsync(cancellationToken: cancellationToken, new object[] { id }); + } - /// - [Obsolete] - public virtual async Task GetBySpecAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - return await ApplySpecification(specification).FirstOrDefaultAsync(cancellationToken); - } + /// + [Obsolete] + public virtual async Task GetBySpecAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + return await ApplySpecification(specification).FirstOrDefaultAsync(cancellationToken); + } - /// - [Obsolete] - public virtual async Task GetBySpecAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - return await ApplySpecification(specification).FirstOrDefaultAsync(cancellationToken); - } + /// + [Obsolete] + public virtual async Task GetBySpecAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + return await ApplySpecification(specification).FirstOrDefaultAsync(cancellationToken); + } - /// - public virtual async Task FirstOrDefaultAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - return await ApplySpecification(specification).FirstOrDefaultAsync(cancellationToken); - } + /// + public virtual async Task FirstOrDefaultAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + return await ApplySpecification(specification).FirstOrDefaultAsync(cancellationToken); + } - /// - public virtual async Task FirstOrDefaultAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - return await ApplySpecification(specification).FirstOrDefaultAsync(cancellationToken); - } + /// + public virtual async Task FirstOrDefaultAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + return await ApplySpecification(specification).FirstOrDefaultAsync(cancellationToken); + } - /// - public virtual async Task SingleOrDefaultAsync(ISingleResultSpecification specification, CancellationToken cancellationToken = default) - { - return await ApplySpecification(specification).SingleOrDefaultAsync(cancellationToken); - } + /// + public virtual async Task SingleOrDefaultAsync(ISingleResultSpecification specification, CancellationToken cancellationToken = default) + { + return await ApplySpecification(specification).SingleOrDefaultAsync(cancellationToken); + } - /// - public virtual async Task SingleOrDefaultAsync(ISingleResultSpecification specification, CancellationToken cancellationToken = default) - { - return await ApplySpecification(specification).SingleOrDefaultAsync(cancellationToken); - } + /// + public virtual async Task SingleOrDefaultAsync(ISingleResultSpecification specification, CancellationToken cancellationToken = default) + { + return await ApplySpecification(specification).SingleOrDefaultAsync(cancellationToken); + } - /// - public virtual async Task> ListAsync(CancellationToken cancellationToken = default) - { - return await dbContext.Set().ToListAsync(cancellationToken); - } + /// + public virtual async Task> ListAsync(CancellationToken cancellationToken = default) + { + return await _dbContext.Set().ToListAsync(cancellationToken); + } - /// - public virtual async Task> ListAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - var queryResult = await ApplySpecification(specification).ToListAsync(cancellationToken); + /// + public virtual async Task> ListAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + var queryResult = await ApplySpecification(specification).ToListAsync(cancellationToken); - return specification.PostProcessingAction == null ? queryResult : specification.PostProcessingAction(queryResult).ToList(); - } + return specification.PostProcessingAction == null ? queryResult : specification.PostProcessingAction(queryResult).ToList(); + } - /// - public virtual async Task> ListAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - var queryResult = await ApplySpecification(specification).ToListAsync(cancellationToken); + /// + public virtual async Task> ListAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + var queryResult = await ApplySpecification(specification).ToListAsync(cancellationToken); - return specification.PostProcessingAction == null ? queryResult : specification.PostProcessingAction(queryResult).ToList(); - } + return specification.PostProcessingAction == null ? queryResult : specification.PostProcessingAction(queryResult).ToList(); + } - /// - public virtual async Task CountAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - return await ApplySpecification(specification, true).CountAsync(cancellationToken); - } + /// + public virtual async Task CountAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + return await ApplySpecification(specification, true).CountAsync(cancellationToken); + } - /// - public virtual async Task CountAsync(CancellationToken cancellationToken = default) - { - return await dbContext.Set().CountAsync(cancellationToken); - } + /// + public virtual async Task CountAsync(CancellationToken cancellationToken = default) + { + return await _dbContext.Set().CountAsync(cancellationToken); + } - /// - public virtual async Task AnyAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - return await ApplySpecification(specification, true).AnyAsync(cancellationToken); - } + /// + public virtual async Task AnyAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + return await ApplySpecification(specification, true).AnyAsync(cancellationToken); + } - /// - public virtual async Task AnyAsync(CancellationToken cancellationToken = default) - { - return await dbContext.Set().AnyAsync(cancellationToken); - } + /// + public virtual async Task AnyAsync(CancellationToken cancellationToken = default) + { + return await _dbContext.Set().AnyAsync(cancellationToken); + } - /// - /// Filters the entities of , to those that match the encapsulated query logic of the - /// . - /// - /// The encapsulated query logic. - /// The filtered entities as an . - protected virtual IQueryable ApplySpecification(ISpecification specification, bool evaluateCriteriaOnly = false) - { - return specificationEvaluator.GetQuery(dbContext.Set().AsQueryable(), specification, evaluateCriteriaOnly); - } + /// + /// Filters the entities of , to those that match the encapsulated query logic of the + /// . + /// + /// The encapsulated query logic. + /// The filtered entities as an . + protected virtual IQueryable ApplySpecification(ISpecification specification, bool evaluateCriteriaOnly = false) + { + return _specificationEvaluator.GetQuery(_dbContext.Set().AsQueryable(), specification, evaluateCriteriaOnly); + } - /// - /// Filters all entities of , that matches the encapsulated query logic of the - /// , from the database. - /// - /// Projects each entity into a new form, being . - /// - /// - /// The type of the value returned by the projection. - /// The encapsulated query logic. - /// The filtered projected entities as an . - protected virtual IQueryable ApplySpecification(ISpecification specification) - { - return specificationEvaluator.GetQuery(dbContext.Set().AsQueryable(), specification); - } + /// + /// Filters all entities of , that matches the encapsulated query logic of the + /// , from the database. + /// + /// Projects each entity into a new form, being . + /// + /// + /// The type of the value returned by the projection. + /// The encapsulated query logic. + /// The filtered projected entities as an . + protected virtual IQueryable ApplySpecification(ISpecification specification) + { + return _specificationEvaluator.GetQuery(_dbContext.Set().AsQueryable(), specification); } } diff --git a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Ardalis.Specification.EntityFramework6.IntegrationTests.csproj b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Ardalis.Specification.EntityFramework6.IntegrationTests.csproj index 459a6493..1b22261b 100644 --- a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Ardalis.Specification.EntityFramework6.IntegrationTests.csproj +++ b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Ardalis.Specification.EntityFramework6.IntegrationTests.csproj @@ -1,7 +1,8 @@ - + net472 + 11.0 Library false true @@ -15,23 +16,24 @@ - - - runtime; build; native; contentfiles; analyzers - all - + + + - - - - - - - + + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive + + runtime; build; native; contentfiles; analyzers + all + @@ -40,4 +42,9 @@ + + + 1701;1702;1591;1573;1712;0612 + + diff --git a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/Configurations/AddressConfiguration.cs b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/Configurations/AddressConfiguration.cs index 40deed39..ce2557aa 100644 --- a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/Configurations/AddressConfiguration.cs +++ b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/Configurations/AddressConfiguration.cs @@ -1,14 +1,13 @@ -using System.Data.Entity.ModelConfiguration; -using Ardalis.Specification.UnitTests.Fixture.Entities; +using Ardalis.Specification.UnitTests.Fixture.Entities; +using System.Data.Entity.ModelConfiguration; -namespace Ardalis.Specification.EntityFramework6.IntegrationTests.Fixture.Configurations +namespace Ardalis.Specification.EntityFramework6.IntegrationTests.Fixture.Configurations; + +public class AddressConfiguration : EntityTypeConfiguration
{ - public class AddressConfiguration : EntityTypeConfiguration
+ public AddressConfiguration() { - public AddressConfiguration() - { - ToTable("Address"); - HasKey(c => c.Id); - } + ToTable("Address"); + HasKey(c => c.Id); } } diff --git a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/Configurations/CompanyConfiguration.cs b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/Configurations/CompanyConfiguration.cs index 8954b787..21ca1302 100644 --- a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/Configurations/CompanyConfiguration.cs +++ b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/Configurations/CompanyConfiguration.cs @@ -1,20 +1,19 @@ -using System.Data.Entity.ModelConfiguration; -using Ardalis.Specification.UnitTests.Fixture.Entities; +using Ardalis.Specification.UnitTests.Fixture.Entities; +using System.Data.Entity.ModelConfiguration; -namespace Ardalis.Specification.EntityFramework6.IntegrationTests.Fixture.Configurations +namespace Ardalis.Specification.EntityFramework6.IntegrationTests.Fixture.Configurations; + +public class CompanyConfiguration : EntityTypeConfiguration { - public class CompanyConfiguration : EntityTypeConfiguration + public CompanyConfiguration() { - public CompanyConfiguration() - { - ToTable("Company"); - HasKey(c => c.Id); + ToTable("Company"); + HasKey(c => c.Id); - Property(c => c.Id) - .HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.None); + Property(c => c.Id) + .HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.None); - //HasMany(c => c.Stores) - // .WithRequired(s => s.Company); - } + //HasMany(c => c.Stores) + // .WithRequired(s => s.Company); } } diff --git a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/Configurations/CountryConfiguration.cs b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/Configurations/CountryConfiguration.cs index ae0c2dfa..653ac7c0 100644 --- a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/Configurations/CountryConfiguration.cs +++ b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/Configurations/CountryConfiguration.cs @@ -1,14 +1,13 @@ -using System.Data.Entity.ModelConfiguration; -using Ardalis.Specification.UnitTests.Fixture.Entities; +using Ardalis.Specification.UnitTests.Fixture.Entities; +using System.Data.Entity.ModelConfiguration; -namespace Ardalis.Specification.EntityFramework6.IntegrationTests.Fixture.Configurations +namespace Ardalis.Specification.EntityFramework6.IntegrationTests.Fixture.Configurations; + +public class CountryConfiguration : EntityTypeConfiguration { - public class CountryConfiguration : EntityTypeConfiguration + public CountryConfiguration() { - public CountryConfiguration() - { - ToTable("Country"); - HasKey(c => c.Id); - } + ToTable("Country"); + HasKey(c => c.Id); } } diff --git a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/Configurations/ProductConfiguration.cs b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/Configurations/ProductConfiguration.cs index e1190982..7e739662 100644 --- a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/Configurations/ProductConfiguration.cs +++ b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/Configurations/ProductConfiguration.cs @@ -1,14 +1,13 @@ -using System.Data.Entity.ModelConfiguration; -using Ardalis.Specification.UnitTests.Fixture.Entities; +using Ardalis.Specification.UnitTests.Fixture.Entities; +using System.Data.Entity.ModelConfiguration; -namespace Ardalis.Specification.EntityFramework6.IntegrationTests.Fixture.Configurations +namespace Ardalis.Specification.EntityFramework6.IntegrationTests.Fixture.Configurations; + +public class ProductConfiguration : EntityTypeConfiguration { - public class ProductConfiguration : EntityTypeConfiguration + public ProductConfiguration() { - public ProductConfiguration() - { - ToTable("Product"); - HasKey(c => c.Id); - } + ToTable("Product"); + HasKey(c => c.Id); } } diff --git a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/Configurations/StoreConfiguration.cs b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/Configurations/StoreConfiguration.cs index 3557f726..1ee87362 100644 --- a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/Configurations/StoreConfiguration.cs +++ b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/Configurations/StoreConfiguration.cs @@ -1,17 +1,16 @@ -using System.Data.Entity.ModelConfiguration; -using Ardalis.Specification.UnitTests.Fixture.Entities; +using Ardalis.Specification.UnitTests.Fixture.Entities; +using System.Data.Entity.ModelConfiguration; -namespace Ardalis.Specification.EntityFramework6.IntegrationTests.Fixture.Configurations +namespace Ardalis.Specification.EntityFramework6.IntegrationTests.Fixture.Configurations; + +public class StoreConfiguration : EntityTypeConfiguration { - public class StoreConfiguration : EntityTypeConfiguration + public StoreConfiguration() { - public StoreConfiguration() - { - ToTable("Store"); - HasKey(c => c.Id); + ToTable("Store"); + HasKey(c => c.Id); - HasOptional(s => s.Address) - .WithRequired(x => x.Store); - } + HasOptional(s => s.Address) + .WithRequired(x => x.Store); } } diff --git a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/DbInitializer.cs b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/DbInitializer.cs index 421db014..736aaa64 100644 --- a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/DbInitializer.cs +++ b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/DbInitializer.cs @@ -1,23 +1,20 @@ -using System.Data.Entity; -using Ardalis.Specification.UnitTests.Fixture.Entities.Seeds; +using Ardalis.Specification.UnitTests.Fixture.Entities.Seeds; +using System.Data.Entity; -namespace Ardalis.Specification.EntityFramework6.IntegrationTests.Fixture +namespace Ardalis.Specification.EntityFramework6.IntegrationTests.Fixture; + +public class DbInitializer : CreateDatabaseIfNotExists { - public class DbInitializer : CreateDatabaseIfNotExists + protected override void Seed(TestDbContext context) { - protected override void Seed(TestDbContext context) - { - base.Seed(context); - - var companies = CompanySeed.Get(); + base.Seed(context); - context.Addresses.AddRange(AddressSeed.Get()); - context.Countries.AddRange(CountrySeed.Get()); - context.Companies.AddRange(CompanySeed.Get()); - context.Products.AddRange(ProductSeed.Get()); - context.Stores.AddRange(StoreSeed.Get()); + context.Addresses.AddRange(AddressSeed.Get()); + context.Countries.AddRange(CountrySeed.Get()); + context.Companies.AddRange(CompanySeed.Get()); + context.Products.AddRange(ProductSeed.Get()); + context.Stores.AddRange(StoreSeed.Get()); - context.SaveChanges(); - } + context.SaveChanges(); } } diff --git a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/IntegrationTestBase.cs b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/IntegrationTestBase.cs index d9dd00b0..c35259da 100644 --- a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/IntegrationTestBase.cs +++ b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/IntegrationTestBase.cs @@ -1,20 +1,19 @@ using Ardalis.Specification.UnitTests.Fixture.Entities; using Xunit; -namespace Ardalis.Specification.EntityFramework6.IntegrationTests.Fixture +namespace Ardalis.Specification.EntityFramework6.IntegrationTests.Fixture; + +public class IntegrationTestBase : IClassFixture { - public class IntegrationTestBase : IClassFixture - { - protected TestDbContext dbContext; - protected Repository companyRepository; - protected Repository storeRepository; + protected TestDbContext dbContext; + protected Repository companyRepository; + protected Repository storeRepository; - public IntegrationTestBase(SharedDatabaseFixture fixture) - { - dbContext = fixture.CreateContext(); + public IntegrationTestBase(SharedDatabaseFixture fixture) + { + dbContext = fixture.CreateContext(); - companyRepository = new Repository(dbContext); - storeRepository = new Repository(dbContext); - } + companyRepository = new Repository(dbContext); + storeRepository = new Repository(dbContext); } } diff --git a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/RepositoryOfT.cs b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/RepositoryOfT.cs index 4f838788..9809bd5b 100644 --- a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/RepositoryOfT.cs +++ b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/RepositoryOfT.cs @@ -1,13 +1,12 @@ -namespace Ardalis.Specification.EntityFramework6.IntegrationTests.Fixture +namespace Ardalis.Specification.EntityFramework6.IntegrationTests.Fixture; + +/// +public class Repository : RepositoryBase where T : class { - /// - public class Repository : RepositoryBase where T : class - { - protected readonly TestDbContext dbContext; + protected readonly TestDbContext dbContext; - public Repository(TestDbContext dbContext) : base(dbContext) - { - this.dbContext = dbContext; - } + public Repository(TestDbContext dbContext) : base(dbContext) + { + this.dbContext = dbContext; } } diff --git a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/SharedDatabaseFixture.cs b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/SharedDatabaseFixture.cs index 1470a4a4..b21710da 100644 --- a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/SharedDatabaseFixture.cs +++ b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/SharedDatabaseFixture.cs @@ -1,47 +1,46 @@ -using System; +using MartinCostello.SqlLocalDb; +using System; using System.Data.Common; using System.Data.SqlClient; -using MartinCostello.SqlLocalDb; -namespace Ardalis.Specification.EntityFramework6.IntegrationTests.Fixture -{ - public class SharedDatabaseFixture : IDisposable - { - // (docker) - public const string ConnectionStringDocker = "Data Source=databaseEF6;Initial Catalog=SpecificationEF6TestsDB;PersistSecurityInfo=True;User ID=sa;Password=P@ssW0rd!"; +namespace Ardalis.Specification.EntityFramework6.IntegrationTests.Fixture; - // (localdb) - public const string ConnectionStringLocalDb = "Server=(localdb)\\mssqllocaldb;Integrated Security=SSPI;Initial Catalog=SpecificationEF6TestsDB;ConnectRetryCount=0"; +public class SharedDatabaseFixture : IDisposable +{ + // (docker) + public const string _connectionStringDocker = "Data Source=databaseEF6;Initial Catalog=SpecificationEF6TestsDB;PersistSecurityInfo=True;User ID=sa;Password=P@ssW0rd!"; + // (localdb) + public const string _connectionStringLocalDb = "Server=(localdb)\\mssqllocaldb;Integrated Security=SSPI;Initial Catalog=SpecificationEF6TestsDB;ConnectRetryCount=0"; - public SharedDatabaseFixture() - { - var isLocalDBInstalled = false; - using (var localDB = new SqlLocalDbApi()) - { - isLocalDBInstalled = localDB.IsLocalDBInstalled(); - } + public SharedDatabaseFixture() + { + var isLocalDBInstalled = false; - Connection = isLocalDBInstalled - ? new SqlConnection(ConnectionStringLocalDb) - : new SqlConnection(ConnectionStringDocker); + using (var localDB = new SqlLocalDbApi()) + { + isLocalDBInstalled = localDB.IsLocalDBInstalled(); } - public DbConnection Connection { get; } + Connection = isLocalDBInstalled + ? new SqlConnection(_connectionStringLocalDb) + : new SqlConnection(_connectionStringDocker); + } - public TestDbContext CreateContext(DbTransaction transaction = null) - { - var context = new TestDbContext(Connection); + public DbConnection Connection { get; } - if (transaction != null) - { - context.Database.UseTransaction(transaction); - } + public TestDbContext CreateContext(DbTransaction transaction = null) + { + var context = new TestDbContext(Connection); - return context; + if (transaction != null) + { + context.Database.UseTransaction(transaction); } - public void Dispose() => Connection.Dispose(); + return context; } + + public void Dispose() => Connection.Dispose(); } diff --git a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/TestDbContext.cs b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/TestDbContext.cs index 2683f3db..4afa5d81 100644 --- a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/TestDbContext.cs +++ b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/TestDbContext.cs @@ -1,39 +1,38 @@ -using System; +using Ardalis.Specification.UnitTests.Fixture.Entities; +using System; using System.Data.Common; using System.Data.Entity; using System.Data.Entity.ModelConfiguration; using System.Linq; using System.Reflection; -using Ardalis.Specification.UnitTests.Fixture.Entities; -namespace Ardalis.Specification.EntityFramework6.IntegrationTests.Fixture +namespace Ardalis.Specification.EntityFramework6.IntegrationTests.Fixture; + +public class TestDbContext : DbContext { - public class TestDbContext : DbContext + public TestDbContext(DbConnection connection) : base(connection, false) { - public TestDbContext(DbConnection connection) : base(connection, false) - { - Database.SetInitializer(new DbInitializer()); - } + Database.SetInitializer(new DbInitializer()); + } - public virtual DbSet Countries { get; set; } - public virtual DbSet Companies { get; set; } - public virtual DbSet Stores { get; set; } - public virtual DbSet
Addresses { get; set; } - public virtual DbSet Products { get; set; } + public virtual DbSet Countries { get; set; } + public virtual DbSet Companies { get; set; } + public virtual DbSet Stores { get; set; } + public virtual DbSet
Addresses { get; set; } + public virtual DbSet Products { get; set; } - protected override void OnModelCreating(DbModelBuilder modelBuilder) + protected override void OnModelCreating(DbModelBuilder modelBuilder) + { + var typesToRegister = Assembly.GetExecutingAssembly().GetTypes() + .Where(type => !string.IsNullOrEmpty(type.Namespace)) + .Where(type => type.BaseType != null && type.BaseType.IsGenericType + && type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>)); + foreach (var type in typesToRegister) { - var typesToRegister = Assembly.GetExecutingAssembly().GetTypes() - .Where(type => !string.IsNullOrEmpty(type.Namespace)) - .Where(type => type.BaseType != null && type.BaseType.IsGenericType - && type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>)); - foreach (var type in typesToRegister) - { - dynamic configurationInstance = Activator.CreateInstance(type); - modelBuilder.Configurations.Add(configurationInstance); - } - - base.OnModelCreating(modelBuilder); + dynamic configurationInstance = Activator.CreateInstance(type); + modelBuilder.Configurations.Add(configurationInstance); } + + base.OnModelCreating(modelBuilder); } } diff --git a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Properties/AssemblyInfo.cs b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Properties/AssemblyInfo.cs index ebb759ea..42c42f1f 100644 --- a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Properties/AssemblyInfo.cs +++ b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following diff --git a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/RepositoryOfT_AnyAsync.cs b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/RepositoryOfT_AnyAsync.cs index c2c527d2..30c1983c 100644 --- a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/RepositoryOfT_AnyAsync.cs +++ b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/RepositoryOfT_AnyAsync.cs @@ -1,38 +1,37 @@ -using System.Threading.Tasks; -using Ardalis.Specification.EntityFramework6.IntegrationTests.Fixture; +using Ardalis.Specification.EntityFramework6.IntegrationTests.Fixture; using Ardalis.Specification.UnitTests.Fixture.Entities.Seeds; using Ardalis.Specification.UnitTests.Fixture.Specs; using FluentAssertions; +using System.Threading.Tasks; using Xunit; -namespace Ardalis.Specification.EntityFramework6.IntegrationTests +namespace Ardalis.Specification.EntityFramework6.IntegrationTests; + +public class RepositoryOfT_AnyAsync : IntegrationTestBase { - public class RepositoryOfT_AnyAsync : IntegrationTestBase - { - public RepositoryOfT_AnyAsync(SharedDatabaseFixture fixture) : base(fixture) { } + public RepositoryOfT_AnyAsync(SharedDatabaseFixture fixture) : base(fixture) { } - [Fact] - public async Task ReturnsTrueOnStoresRecords_WithoutSpec() - { - var result = await storeRepository.AnyAsync(); + [Fact] + public async Task ReturnsTrueOnStoresRecords_WithoutSpec() + { + var result = await storeRepository.AnyAsync(); - result.Should().BeTrue(); - } + result.Should().BeTrue(); + } - [Fact] - public async Task ReturnsTrue_GivenStoreByIdSpecWithValidStore() - { - var result = await storeRepository.AnyAsync(new StoreByIdSpec(StoreSeed.VALID_STORE_ID)); + [Fact] + public async Task ReturnsTrue_GivenStoreByIdSpecWithValidStore() + { + var result = await storeRepository.AnyAsync(new StoreByIdSpec(StoreSeed.VALID_STORE_ID)); - result.Should().BeTrue(); - } + result.Should().BeTrue(); + } - [Fact] - public async Task ReturnsFalse_GivenStoreByIdSpecWithInvalidStore() - { - var result = await storeRepository.AnyAsync(new StoreByIdSpec(0)); + [Fact] + public async Task ReturnsFalse_GivenStoreByIdSpecWithInvalidStore() + { + var result = await storeRepository.AnyAsync(new StoreByIdSpec(0)); - result.Should().BeFalse(); - } + result.Should().BeFalse(); } } diff --git a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/RepositoryOfT_GetById.cs b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/RepositoryOfT_GetById.cs index d6667e7b..7aab7214 100644 --- a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/RepositoryOfT_GetById.cs +++ b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/RepositoryOfT_GetById.cs @@ -1,31 +1,30 @@ -using System.Threading.Tasks; -using Ardalis.Specification.EntityFramework6.IntegrationTests.Fixture; +using Ardalis.Specification.EntityFramework6.IntegrationTests.Fixture; using Ardalis.Specification.UnitTests.Fixture.Entities.Seeds; using FluentAssertions; +using System.Threading.Tasks; using Xunit; -namespace Ardalis.Specification.EntityFramework6.IntegrationTests +namespace Ardalis.Specification.EntityFramework6.IntegrationTests; + +public class RepositoryOfT_GetById : IntegrationTestBase { - public class RepositoryOfT_GetById : IntegrationTestBase - { - public RepositoryOfT_GetById(SharedDatabaseFixture fixture) : base(fixture) { } + public RepositoryOfT_GetById(SharedDatabaseFixture fixture) : base(fixture) { } - [Fact] - public async Task ReturnsStore_GivenId() - { - var result = await storeRepository.GetByIdAsync(StoreSeed.VALID_STORE_ID); + [Fact] + public async Task ReturnsStore_GivenId() + { + var result = await storeRepository.GetByIdAsync(StoreSeed.VALID_STORE_ID); - result.Should().NotBeNull(); - result.Name.Should().Be(StoreSeed.VALID_STORE_NAME); - } + result.Should().NotBeNull(); + result.Name.Should().Be(StoreSeed.VALID_STORE_NAME); + } - [Fact] - public async Task ReturnsStore_GivenGenericId() - { - var result = await storeRepository.GetByIdAsync(StoreSeed.VALID_STORE_ID); + [Fact] + public async Task ReturnsStore_GivenGenericId() + { + var result = await storeRepository.GetByIdAsync(StoreSeed.VALID_STORE_ID); - result.Should().NotBeNull(); - result.Name.Should().Be(StoreSeed.VALID_STORE_NAME); - } + result.Should().NotBeNull(); + result.Name.Should().Be(StoreSeed.VALID_STORE_NAME); } } diff --git a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/RepositoryOfT_GetBySpec.cs b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/RepositoryOfT_GetBySpec.cs index a9d610af..14438e2e 100644 --- a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/RepositoryOfT_GetBySpec.cs +++ b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/RepositoryOfT_GetBySpec.cs @@ -1,104 +1,103 @@ -using System.Data.Entity; -using System.Linq; -using System.Threading.Tasks; -using Ardalis.Specification.EntityFramework6.IntegrationTests.Fixture; +using Ardalis.Specification.EntityFramework6.IntegrationTests.Fixture; using Ardalis.Specification.UnitTests.Fixture.Entities.Seeds; using Ardalis.Specification.UnitTests.Fixture.Specs; using FluentAssertions; +using System.Data.Entity; +using System.Linq; +using System.Threading.Tasks; using Xunit; -namespace Ardalis.Specification.EntityFramework6.IntegrationTests +namespace Ardalis.Specification.EntityFramework6.IntegrationTests; + +public class RepositoryOfT_GetBySpec : IntegrationTestBase { - public class RepositoryOfT_GetBySpec : IntegrationTestBase + public RepositoryOfT_GetBySpec(SharedDatabaseFixture fixture) : base(fixture) { } + + [Fact] + public async Task ReturnsStoreWithProducts_GivenStoreByIdIncludeProductsSpec() + { + var result = await storeRepository.GetBySpecAsync(new StoreByIdIncludeProductsSpec(StoreSeed.VALID_STORE_ID)); + + result.Should().NotBeNull(); + result.Name.Should().Be(StoreSeed.VALID_STORE_NAME); + result.Products.Count.Should().BeGreaterThan(1); + } + + [Fact] + public async Task ReturnsStoreWithAddress_GivenStoreByIdIncludeAddressSpec() + { + var result = await storeRepository.GetBySpecAsync(new StoreByIdIncludeAddressSpec(StoreSeed.VALID_STORE_ID)); + + result.Should().NotBeNull(); + result.Name.Should().Be(StoreSeed.VALID_STORE_NAME); + result.Address?.Street.Should().Be(AddressSeed.VALID_STREET_FOR_STOREID1); + } + + [Fact] + public async Task ReturnsStoreWithAddressAndProduct_GivenStoreByIdIncludeAddressAndProductsSpec() + { + var result = await storeRepository.GetBySpecAsync(new StoreByIdIncludeAddressAndProductsSpec(StoreSeed.VALID_STORE_ID)); + + result.Should().NotBeNull(); + result.Name.Should().Be(StoreSeed.VALID_STORE_NAME); + result.Products.Count.Should().BeGreaterThan(1); + result.Address?.Street.Should().Be(AddressSeed.VALID_STREET_FOR_STOREID1); + } + + [Fact] + public async Task ReturnsStoreWithProducts_GivenStoreByIdIncludeProductsUsingStringSpec() + { + var result = await storeRepository.GetBySpecAsync(new StoreByIdIncludeProductsUsingStringSpec(StoreSeed.VALID_STORE_ID)); + + result.Should().NotBeNull(); + result.Name.Should().Be(StoreSeed.VALID_STORE_NAME); + result.Products.Count.Should().BeGreaterThan(1); + } + + [Fact] + public async Task ReturnsCompanyWithStoresAndAddress_GivenCompanyByIdIncludeStoresThenIncludeAddressSpec() + { + var result = await companyRepository.GetBySpecAsync(new CompanyByIdIncludeStoresThenIncludeAddressSpec(CompanySeed.VALID_COMPANY_ID)); + + result.Should().NotBeNull(); + result.Name.Should().Be(CompanySeed.VALID_COMPANY_NAME); + result.Stores.Count.Should().BeGreaterThan(49); + result.Stores.Select(x => x.Address).Count().Should().BeGreaterThan(0); + } + + [Fact] + public async Task ReturnsCompanyWithStoresAndProducts_GivenCompanyByIdIncludeStoresThenIncludeProductsSpec() + { + var result = await companyRepository.GetBySpecAsync(new CompanyByIdIncludeStoresThenIncludeProductsSpec(CompanySeed.VALID_COMPANY_ID)); + + result.Should().NotBeNull(); + result.Name.Should().Be(CompanySeed.VALID_COMPANY_NAME); + result.Stores.Count.Should().BeGreaterThan(49); + result.Stores.Select(x => x.Products).Count().Should().BeGreaterThan(1); + } + + [Fact] + public async Task ReturnsUntrackedCompany_GivenCompanyByIdAsUntrackedSpec() + { + //dbContext.ChangeTracker.Clear(); + + var result = await companyRepository.GetBySpecAsync(new CompanyByIdAsUntrackedSpec(CompanySeed.VALID_COMPANY_ID)); + + result.Should().NotBeNull(); + result?.Name.Should().Be(CompanySeed.VALID_COMPANY_NAME); + dbContext.Entry(result).State.Should().Be(EntityState.Detached); + } + + [Fact] + public async Task ReturnsStoreWithCompanyAndCountryAndStoresForCompany_GivenStoreByIdIncludeCompanyAndCountryAndStoresForCompanySpec() { - public RepositoryOfT_GetBySpec(SharedDatabaseFixture fixture) : base(fixture) { } - - [Fact] - public async Task ReturnsStoreWithProducts_GivenStoreByIdIncludeProductsSpec() - { - var result = await storeRepository.GetBySpecAsync(new StoreByIdIncludeProductsSpec(StoreSeed.VALID_STORE_ID)); - - result.Should().NotBeNull(); - result.Name.Should().Be(StoreSeed.VALID_STORE_NAME); - result.Products.Count.Should().BeGreaterThan(1); - } - - [Fact] - public async Task ReturnsStoreWithAddress_GivenStoreByIdIncludeAddressSpec() - { - var result = await storeRepository.GetBySpecAsync(new StoreByIdIncludeAddressSpec(StoreSeed.VALID_STORE_ID)); - - result.Should().NotBeNull(); - result.Name.Should().Be(StoreSeed.VALID_STORE_NAME); - result.Address?.Street.Should().Be(AddressSeed.VALID_STREET_FOR_STOREID1); - } - - [Fact] - public async Task ReturnsStoreWithAddressAndProduct_GivenStoreByIdIncludeAddressAndProductsSpec() - { - var result = await storeRepository.GetBySpecAsync(new StoreByIdIncludeAddressAndProductsSpec(StoreSeed.VALID_STORE_ID)); - - result.Should().NotBeNull(); - result.Name.Should().Be(StoreSeed.VALID_STORE_NAME); - result.Products.Count.Should().BeGreaterThan(1); - result.Address?.Street.Should().Be(AddressSeed.VALID_STREET_FOR_STOREID1); - } - - [Fact] - public async Task ReturnsStoreWithProducts_GivenStoreByIdIncludeProductsUsingStringSpec() - { - var result = await storeRepository.GetBySpecAsync(new StoreByIdIncludeProductsUsingStringSpec(StoreSeed.VALID_STORE_ID)); - - result.Should().NotBeNull(); - result.Name.Should().Be(StoreSeed.VALID_STORE_NAME); - result.Products.Count.Should().BeGreaterThan(1); - } - - [Fact] - public async Task ReturnsCompanyWithStoresAndAddress_GivenCompanyByIdIncludeStoresThenIncludeAddressSpec() - { - var result = await companyRepository.GetBySpecAsync(new CompanyByIdIncludeStoresThenIncludeAddressSpec(CompanySeed.VALID_COMPANY_ID)); - - result.Should().NotBeNull(); - result.Name.Should().Be(CompanySeed.VALID_COMPANY_NAME); - result.Stores.Count.Should().BeGreaterThan(49); - result.Stores.Select(x => x.Address).Count().Should().BeGreaterThan(0); - } - - [Fact] - public async Task ReturnsCompanyWithStoresAndProducts_GivenCompanyByIdIncludeStoresThenIncludeProductsSpec() - { - var result = await companyRepository.GetBySpecAsync(new CompanyByIdIncludeStoresThenIncludeProductsSpec(CompanySeed.VALID_COMPANY_ID)); - - result.Should().NotBeNull(); - result.Name.Should().Be(CompanySeed.VALID_COMPANY_NAME); - result.Stores.Count.Should().BeGreaterThan(49); - result.Stores.Select(x => x.Products).Count().Should().BeGreaterThan(1); - } - - [Fact] - public async Task ReturnsUntrackedCompany_GivenCompanyByIdAsUntrackedSpec() - { - //dbContext.ChangeTracker.Clear(); - - var result = await companyRepository.GetBySpecAsync(new CompanyByIdAsUntrackedSpec(CompanySeed.VALID_COMPANY_ID)); - - result.Should().NotBeNull(); - result?.Name.Should().Be(CompanySeed.VALID_COMPANY_NAME); - dbContext.Entry(result).State.Should().Be(EntityState.Detached); - } - - [Fact] - public async Task ReturnsStoreWithCompanyAndCountryAndStoresForCompany_GivenStoreByIdIncludeCompanyAndCountryAndStoresForCompanySpec() - { - var result = await storeRepository.GetBySpecAsync(new StoreByIdIncludeCompanyAndCountryAndStoresForCompanySpec(StoreSeed.VALID_STORE_ID)); - - result.Should().NotBeNull(); - result.Name.Should().Be(StoreSeed.VALID_STORE_NAME); - result.Company.Should().NotBeNull(); - result.Company?.Country.Should().NotBeNull(); - result.Company?.Stores.Should().HaveCountGreaterOrEqualTo(2); - result.Company?.Stores?.Should().Match(x => x.Any(z => z.Products.Count > 0)); - } + var result = await storeRepository.GetBySpecAsync(new StoreByIdIncludeCompanyAndCountryAndStoresForCompanySpec(StoreSeed.VALID_STORE_ID)); + + result.Should().NotBeNull(); + result.Name.Should().Be(StoreSeed.VALID_STORE_NAME); + result.Company.Should().NotBeNull(); + result.Company?.Country.Should().NotBeNull(); + result.Company?.Stores.Should().HaveCountGreaterOrEqualTo(2); + result.Company?.Stores?.Should().Match(x => x.Any(z => z.Products.Count > 0)); } } diff --git a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/RepositoryOfT_ListAsync.cs b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/RepositoryOfT_ListAsync.cs index 97ff4d67..0f3a57c3 100644 --- a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/RepositoryOfT_ListAsync.cs +++ b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/RepositoryOfT_ListAsync.cs @@ -1,184 +1,183 @@ -using System.Linq; -using System.Threading.Tasks; -using Ardalis.Specification.EntityFramework6.IntegrationTests.Fixture; +using Ardalis.Specification.EntityFramework6.IntegrationTests.Fixture; using Ardalis.Specification.UnitTests.Fixture.Entities.Seeds; using Ardalis.Specification.UnitTests.Fixture.Specs; using FluentAssertions; +using System.Linq; +using System.Threading.Tasks; using Xunit; -namespace Ardalis.Specification.EntityFramework6.IntegrationTests +namespace Ardalis.Specification.EntityFramework6.IntegrationTests; + +public class RepositoryOfT_ListAsync : IntegrationTestBase { - public class RepositoryOfT_ListAsync : IntegrationTestBase + public RepositoryOfT_ListAsync(SharedDatabaseFixture fixture) : base(fixture) { } + + [Fact] + public async Task ReturnsStoreWithProducts_GivenStoreIncludeProductsSpec() + { + var result = await storeRepository.ListAsync(new StoreIncludeProductsSpec()); + + result.Should().NotBeNull(); + result.Should().NotBeEmpty(); + result[0].Products.Should().NotBeEmpty(); + } + + [Fact] + public async Task ReturnsStoreWithAddress_GivenStoreIncludeAddressSpec() + { + var result = await storeRepository.ListAsync(new StoreIncludeAddressSpec()); + + result.Should().NotBeNull(); + result.Should().NotBeEmpty(); + result[0].Address.Should().NotBeNull(); + } + + [Fact] + public async Task ReturnsStoreWithAddressAndProduct_GivenStoreIncludeAddressAndProductsSpec() { - public RepositoryOfT_ListAsync(SharedDatabaseFixture fixture) : base(fixture) { } - - [Fact] - public async Task ReturnsStoreWithProducts_GivenStoreIncludeProductsSpec() - { - var result = await storeRepository.ListAsync(new StoreIncludeProductsSpec()); + var result = await storeRepository.ListAsync(new StoreIncludeAddressAndProductsSpec()); - result.Should().NotBeNull(); - result.Should().NotBeEmpty(); - result[0].Products.Should().NotBeEmpty(); - } - - [Fact] - public async Task ReturnsStoreWithAddress_GivenStoreIncludeAddressSpec() - { - var result = await storeRepository.ListAsync(new StoreIncludeAddressSpec()); - - result.Should().NotBeNull(); - result.Should().NotBeEmpty(); - result[0].Address.Should().NotBeNull(); - } + result.Should().NotBeNull(); + result.Should().NotBeEmpty(); + result[0].Address.Should().NotBeNull(); + result[0].Products.Should().NotBeEmpty(); + } - [Fact] - public async Task ReturnsStoreWithAddressAndProduct_GivenStoreIncludeAddressAndProductsSpec() - { - var result = await storeRepository.ListAsync(new StoreIncludeAddressAndProductsSpec()); + [Fact] + public async Task ReturnsStoreWithIdFrom15To30_GivenStoresByIdListSpec() + { + var ids = Enumerable.Range(15, 16); + var spec = new StoresByIdListSpec(ids); - result.Should().NotBeNull(); - result.Should().NotBeEmpty(); - result[0].Address.Should().NotBeNull(); - result[0].Products.Should().NotBeEmpty(); - } + var stores = await storeRepository.ListAsync(spec); - [Fact] - public async Task ReturnsStoreWithIdFrom15To30_GivenStoresByIdListSpec() - { - var ids = Enumerable.Range(15, 16); - var spec = new StoresByIdListSpec(ids); + stores.Count.Should().Be(16); + stores.OrderBy(x => x.Id).First().Id.Should().Be(15); + stores.OrderBy(x => x.Id).Last().Id.Should().Be(30); + } - var stores = await storeRepository.ListAsync(spec); + [Fact] + public async Task ReturnsSecondPageOfStoreNames_GivenStoreNamesPaginatedSpec() + { + var take = 10; // pagesize 10 + var skip = (2 - 1) * 10; // page 2 - stores.Count.Should().Be(16); - stores.OrderBy(x => x.Id).First().Id.Should().Be(15); - stores.OrderBy(x => x.Id).Last().Id.Should().Be(30); - } + var spec = new StoreNamesPaginatedSpec(skip, take); - [Fact] - public async Task ReturnsSecondPageOfStoreNames_GivenStoreNamesPaginatedSpec() - { - int take = 10; // pagesize 10 - int skip = (2 - 1) * 10; // page 2 + var storeNames = await storeRepository.ListAsync(spec); - var spec = new StoreNamesPaginatedSpec(skip, take); + storeNames.Count.Should().Be(take); + storeNames.First().Should().Be("Store 11"); + storeNames.Last().Should().Be("Store 20"); + } - var storeNames = await storeRepository.ListAsync(spec); + [Fact] + public async Task ReturnsSecondPageOfStores_GivenStoresPaginatedSpec() + { + var take = 10; // pagesize 10 + var skip = (2 - 1) * 10; // page 2 - storeNames.Count.Should().Be(take); - storeNames.First().Should().Be("Store 11"); - storeNames.Last().Should().Be("Store 20"); - } + var spec = new StoresPaginatedSpec(skip, take); - [Fact] - public async Task ReturnsSecondPageOfStores_GivenStoresPaginatedSpec() - { - int take = 10; // pagesize 10 - int skip = (2 - 1) * 10; // page 2 + var stores = await storeRepository.ListAsync(spec); - var spec = new StoresPaginatedSpec(skip, take); - - var stores = await storeRepository.ListAsync(spec); - - stores.Count.Should().Be(take); - stores.OrderBy(x => x.Id).First().Id.Should().Be(11); - stores.OrderBy(x => x.Id).Last().Id.Should().Be(20); - } - - [Fact] - public async Task ReturnsOrderStoresByNameDescForCompanyWithId2_GivenStoresByCompanyOrderedDescByNameSpec() - { - var spec = new StoresByCompanyOrderedDescByNameSpec(2); - - var stores = await storeRepository.ListAsync(spec); - - stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_FIRST_ID); - stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_LAST_ID); - } - - [Fact] - public async Task ReturnsOrderStoresByNameDescThenByIdForCompanyWithId2_GivenStoresByCompanyOrderedDescByNameThenByIdSpec() - { - var spec = new StoresByCompanyOrderedDescByNameThenByIdSpec(2); - - var stores = await storeRepository.ListAsync(spec); - - stores.First().Id.Should().Be(99); - stores.Last().Id.Should().Be(98); - } - - [Fact] - public async Task ReturnsSecondPageOfStoresForCompanyWithId2_GivenStoresByCompanyPaginatedOrderedDescByNameSpec() - { - int take = 10; // pagesize 10 - int skip = (2 - 1) * 10; // page 2 - - var spec = new StoresByCompanyPaginatedOrderedDescByNameSpec(2, skip, take); - - var stores = await storeRepository.ListAsync(spec); - - stores.Count.Should().Be(take); - stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_PAGE2_FIRST_ID); - stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_PAGE2_LAST_ID); - } - - [Fact] - public async Task ReturnsSecondPageOfStoresForCompanyWithId2_GivenStoresByCompanyPaginatedSpec() - { - int take = 10; // pagesize 10 - int skip = (2 - 1) * 10; // page 2 - - var spec = new StoresByCompanyPaginatedSpec(2, skip, take); + stores.Count.Should().Be(take); + stores.OrderBy(x => x.Id).First().Id.Should().Be(11); + stores.OrderBy(x => x.Id).Last().Id.Should().Be(20); + } - var stores = await storeRepository.ListAsync(spec); - - stores.Count.Should().Be(take); - stores.OrderBy(x => x.Id).First().Id.Should().Be(61); - stores.OrderBy(x => x.Id).Last().Id.Should().Be(70); - } + [Fact] + public async Task ReturnsOrderStoresByNameDescForCompanyWithId2_GivenStoresByCompanyOrderedDescByNameSpec() + { + var spec = new StoresByCompanyOrderedDescByNameSpec(2); - [Fact] - public async Task ReturnsOrderedStores_GivenStoresOrderedSpecByName() - { - var spec = new StoresOrderedSpecByName(); + var stores = await storeRepository.ListAsync(spec); - var stores = await storeRepository.ListAsync(spec); + stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_FIRST_ID); + stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_LAST_ID); + } - stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_FIRST_ID); - stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_LAST_ID); - } + [Fact] + public async Task ReturnsOrderStoresByNameDescThenByIdForCompanyWithId2_GivenStoresByCompanyOrderedDescByNameThenByIdSpec() + { + var spec = new StoresByCompanyOrderedDescByNameThenByIdSpec(2); - [Fact] - public async Task ReturnsOrderedStores_GivenStoresOrderedDescendingByNameSpec() - { - var spec = new StoresOrderedDescendingByNameSpec(); + var stores = await storeRepository.ListAsync(spec); - var stores = await storeRepository.ListAsync(spec); + stores.First().Id.Should().Be(99); + stores.Last().Id.Should().Be(98); + } - stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FIRST_ID); - stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_LAST_ID); - } + [Fact] + public async Task ReturnsSecondPageOfStoresForCompanyWithId2_GivenStoresByCompanyPaginatedOrderedDescByNameSpec() + { + var take = 10; // pagesize 10 + var skip = (2 - 1) * 10; // page 2 - [Fact] - public async Task ReturnsStoreContainingCity1_GivenStoreIncludeProductsSpec() - { - var result = await storeRepository.ListAsync(new StoreSearchByNameOrCitySpec(StoreSeed.VALID_Search_City_Key)); + var spec = new StoresByCompanyPaginatedOrderedDescByNameSpec(2, skip, take); - result.Should().NotBeNull(); - result.Should().ContainSingle(); - result[0].Id.Should().Be(StoreSeed.VALID_Search_ID); - result[0].City.Should().Contain(StoreSeed.VALID_Search_City_Key); - } + var stores = await storeRepository.ListAsync(spec); - [Fact] - public virtual async Task ReturnsAllProducts_GivenStoreSelectManyProductsSpec() - { - var result = await storeRepository.ListAsync(new StoreProductNamesSpec()); + stores.Count.Should().Be(take); + stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_PAGE2_FIRST_ID); + stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_PAGE2_LAST_ID); + } + + [Fact] + public async Task ReturnsSecondPageOfStoresForCompanyWithId2_GivenStoresByCompanyPaginatedSpec() + { + var take = 10; // pagesize 10 + var skip = (2 - 1) * 10; // page 2 + + var spec = new StoresByCompanyPaginatedSpec(2, skip, take); + + var stores = await storeRepository.ListAsync(spec); + + stores.Count.Should().Be(take); + stores.OrderBy(x => x.Id).First().Id.Should().Be(61); + stores.OrderBy(x => x.Id).Last().Id.Should().Be(70); + } + + [Fact] + public async Task ReturnsOrderedStores_GivenStoresOrderedSpecByName() + { + var spec = new StoresOrderedSpecByName(); + + var stores = await storeRepository.ListAsync(spec); + + stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_FIRST_ID); + stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_LAST_ID); + } + + [Fact] + public async Task ReturnsOrderedStores_GivenStoresOrderedDescendingByNameSpec() + { + var spec = new StoresOrderedDescendingByNameSpec(); + + var stores = await storeRepository.ListAsync(spec); + + stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FIRST_ID); + stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_LAST_ID); + } + + [Fact] + public async Task ReturnsStoreContainingCity1_GivenStoreIncludeProductsSpec() + { + var result = await storeRepository.ListAsync(new StoreSearchByNameOrCitySpec(StoreSeed.VALID_Search_City_Key)); + + result.Should().NotBeNull(); + result.Should().ContainSingle(); + result[0].Id.Should().Be(StoreSeed.VALID_Search_ID); + result[0].City.Should().Contain(StoreSeed.VALID_Search_City_Key); + } + + [Fact] + public virtual async Task ReturnsAllProducts_GivenStoreSelectManyProductsSpec() + { + var result = await storeRepository.ListAsync(new StoreProductNamesSpec()); - result.Should().NotBeNull(); - result.Should().HaveCount(ProductSeed.TOTAL_PRODUCT_COUNT); - result.OrderBy(x => x).First().Should().Be(ProductSeed.VALID_PRODUCT_NAME); - } + result.Should().NotBeNull(); + result.Should().HaveCount(ProductSeed.TOTAL_PRODUCT_COUNT); + result.OrderBy(x => x).First().Should().Be(ProductSeed.VALID_PRODUCT_NAME); } } diff --git a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Ardalis.Specification.EntityFrameworkCore.csproj b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Ardalis.Specification.EntityFrameworkCore.csproj index e6db8b37..3105a170 100644 --- a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Ardalis.Specification.EntityFrameworkCore.csproj +++ b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Ardalis.Specification.EntityFrameworkCore.csproj @@ -2,50 +2,57 @@ net6.0 + 11.0 + enable + enable + + Ardalis.Specification.EntityFrameworkCore Ardalis.Specification.EntityFrameworkCore Ardalis.Specification.EntityFrameworkCore true Steve Smith (@ardalis); Fati Iseni (@fiseni); Scott DePouw Ardalis.com - https://github.com/ardalis/specification EF Core plugin package to Ardalis.Specification containing EF Core evaluator and abstract repository. EF Core plugin package to Ardalis.Specification containing EF Core evaluator and abstract repository. + https://github.com/ardalis/specification https://github.com/ardalis/specification spec;specification;repository;ddd;ef;ef core;entity framework;entity framework core + icon.png 7.0.0 - * Patch 2 by @davidhenley in https://github.com/ardalis/Specification/pull/283 - * Fix `Just the Docs` link in docs home page by @snowfrogdev in https://github.com/ardalis/Specification/pull/293 - * Update url path by @ta1H3n in https://github.com/ardalis/Specification/pull/303 - * Implement SelectMany support by @amdavie in https://github.com/ardalis/Specification/pull/320 - * Add two methods for consuming repositories in scenarios where repositories could be longer lived (e.g. Blazor component Injections) by @jasonsummers in https://github.com/ardalis/Specification/pull/289 - * Added support for AsAsyncEnumerable by @nkz-soft in https://github.com/ardalis/Specification/pull/316 - * Lamadelrae/doc faq ef versions by @Lamadelrae in https://github.com/ardalis/Specification/pull/324 - * Updated projects, drop support for old TFMs. by @fiseni in https://github.com/ardalis/Specification/pull/326 - * Update the search feature to generate parameterized query. by @fiseni in https://github.com/ardalis/Specification/pull/327 - * Add support for extending default evaluator list by @fiseni in https://github.com/ardalis/Specification/pull/328 - * Ardalis/cleanup by @ardalis in https://github.com/ardalis/Specification/pull/332 - Ardalis.Specification.EntityFrameworkCore - icon.png + * Patch 2 by @davidhenley in https://github.com/ardalis/Specification/pull/283 + * Fix `Just the Docs` link in docs home page by @snowfrogdev in https://github.com/ardalis/Specification/pull/293 + * Update url path by @ta1H3n in https://github.com/ardalis/Specification/pull/303 + * Implement SelectMany support by @amdavie in https://github.com/ardalis/Specification/pull/320 + * Add two methods for consuming repositories in scenarios where repositories could be longer lived (e.g. Blazor component Injections) by @jasonsummers in https://github.com/ardalis/Specification/pull/289 + * Added support for AsAsyncEnumerable by @nkz-soft in https://github.com/ardalis/Specification/pull/316 + * Lamadelrae/doc faq ef versions by @Lamadelrae in https://github.com/ardalis/Specification/pull/324 + * Updated projects, drop support for old TFMs. by @fiseni in https://github.com/ardalis/Specification/pull/326 + * Update the search feature to generate parameterized query. by @fiseni in https://github.com/ardalis/Specification/pull/327 + * Add support for extending default evaluator list by @fiseni in https://github.com/ardalis/Specification/pull/328 + * Ardalis/cleanup by @ardalis in https://github.com/ardalis/Specification/pull/332 + true true $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb - 9.0 - enable bin\$(Configuration)\Ardalis.Specification.EntityFrameworkCore.xml - - + + - + - + - + + + + 1701;1702;1591;1573;1712 + diff --git a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/CachedReadConcurrentDictionary.cs b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/CachedReadConcurrentDictionary.cs index 5245dfce..3c2dc912 100644 --- a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/CachedReadConcurrentDictionary.cs +++ b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/CachedReadConcurrentDictionary.cs @@ -1,233 +1,223 @@ -using System; -using System.Collections; +using System.Collections; using System.Collections.Concurrent; -using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; -using System.Threading; -namespace Ardalis.Specification.EntityFrameworkCore +namespace Ardalis.Specification.EntityFrameworkCore; + +/// +/// A thread-safe dictionary for read-heavy workloads. +/// +/// The key type. +/// The value type. +internal class CachedReadConcurrentDictionary : IDictionary where TKey : notnull { /// - /// A thread-safe dictionary for read-heavy workloads. + /// The number of cache misses which are tolerated before the cache is regenerated. /// - /// The key type. - /// The value type. - internal class CachedReadConcurrentDictionary : IDictionary where TKey : notnull - { - /// - /// The number of cache misses which are tolerated before the cache is regenerated. - /// - private const int CacheMissesBeforeCaching = 10; - private readonly ConcurrentDictionary dictionary; - private readonly IEqualityComparer? comparer; - - /// - /// Approximate number of reads which did not hit the cache since it was last invalidated. - /// This is used as a heuristic that the dictionary is not being modified frequently with respect to the read volume. - /// - private int cacheMissReads; - - /// - /// Cached version of . - /// - private Dictionary? readCache; - - /// - /// Initializes a new instance of the class. - /// - public CachedReadConcurrentDictionary() - { - this.dictionary = new ConcurrentDictionary(); - } + private const int _cacheMissesBeforeCaching = 10; + private readonly ConcurrentDictionary _dictionary; + private readonly IEqualityComparer? _comparer; - /// - /// Initializes a new instance of the class - /// that contains elements copied from the specified collection. - /// - /// - /// The whose elements are copied to the new instance. - /// - public CachedReadConcurrentDictionary(IEnumerable> collection) - { - this.dictionary = new ConcurrentDictionary(collection); - } + /// + /// Approximate number of reads which did not hit the cache since it was last invalidated. + /// This is used as a heuristic that the dictionary is not being modified frequently with respect to the read volume. + /// + private int _cacheMissReads; - /// - /// Initializes a new instance of the class - /// that contains elements copied from the specified collection and uses the specified - /// . - /// - /// - /// The implementation to use when comparing keys. - /// - public CachedReadConcurrentDictionary(IEqualityComparer comparer) - { - this.comparer = comparer; - this.dictionary = new ConcurrentDictionary(comparer); - } + /// + /// Cached version of . + /// + private Dictionary? _readCache; - /// - /// Initializes a new instance of the - /// class that contains elements copied from the specified collection and uses the specified - /// . - /// - /// - /// The whose elements are copied to the new instance. - /// - /// - /// The implementation to use when comparing keys. - /// - public CachedReadConcurrentDictionary(IEnumerable> collection, IEqualityComparer comparer) - { - this.comparer = comparer; - this.dictionary = new ConcurrentDictionary(collection, comparer); - } + /// + /// Initializes a new instance of the class. + /// + public CachedReadConcurrentDictionary() + { + _dictionary = new ConcurrentDictionary(); + } - /// - IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator(); + /// + /// Initializes a new instance of the class + /// that contains elements copied from the specified collection. + /// + /// + /// The whose elements are copied to the new instance. + /// + public CachedReadConcurrentDictionary(IEnumerable> collection) + { + _dictionary = new ConcurrentDictionary(collection); + } - /// - public IEnumerator> GetEnumerator() => this.GetReadDictionary().GetEnumerator(); + /// + /// Initializes a new instance of the class + /// that contains elements copied from the specified collection and uses the specified + /// . + /// + /// + /// The implementation to use when comparing keys. + /// + public CachedReadConcurrentDictionary(IEqualityComparer comparer) + { + _comparer = comparer; + _dictionary = new ConcurrentDictionary(comparer); + } - /// - public void Add(KeyValuePair item) - { - ((IDictionary)this.dictionary).Add(item); - this.InvalidateCache(); - } + /// + /// Initializes a new instance of the + /// class that contains elements copied from the specified collection and uses the specified + /// . + /// + /// + /// The whose elements are copied to the new instance. + /// + /// + /// The implementation to use when comparing keys. + /// + public CachedReadConcurrentDictionary(IEnumerable> collection, IEqualityComparer comparer) + { + _comparer = comparer; + _dictionary = new ConcurrentDictionary(collection, comparer); + } - /// - public void Clear() - { - this.dictionary.Clear(); - this.InvalidateCache(); - } + /// + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - /// - public bool Contains(KeyValuePair item) => this.GetReadDictionary().Contains(item); + /// + public IEnumerator> GetEnumerator() => GetReadDictionary().GetEnumerator(); - /// - public void CopyTo(KeyValuePair[] array, int arrayIndex) - { - this.GetReadDictionary().CopyTo(array, arrayIndex); - } + /// + public void Add(KeyValuePair item) + { + ((IDictionary)_dictionary).Add(item); + InvalidateCache(); + } - /// - public bool Remove(KeyValuePair item) - { - var result = ((IDictionary)this.dictionary).Remove(item); - if (result) this.InvalidateCache(); - return result; - } + /// + public void Clear() + { + _dictionary.Clear(); + InvalidateCache(); + } - /// - public int Count => this.GetReadDictionary().Count; + /// + public bool Contains(KeyValuePair item) => GetReadDictionary().Contains(item); - /// - public bool IsReadOnly => false; + /// + public void CopyTo(KeyValuePair[] array, int arrayIndex) + { + GetReadDictionary().CopyTo(array, arrayIndex); + } - /// - public void Add(TKey key, TValue value) - { - ((IDictionary)this.dictionary).Add(key, value); - this.InvalidateCache(); - } + /// + public bool Remove(KeyValuePair item) + { + var result = ((IDictionary)_dictionary).Remove(item); + if (result) InvalidateCache(); + return result; + } - /// - /// Adds a key/value pair to the if the key does not exist. - /// - /// The key of the element to add. - /// The function used to generate a value for the key - /// The value for the key. This will be either the existing value for the key if the key is already in the dictionary, or the new value if the key was not in the dictionary. - public TValue GetOrAdd(TKey key, Func valueFactory) - { - if (this.GetReadDictionary().TryGetValue(key, out var value)) - { - return value; - } + /// + public int Count => GetReadDictionary().Count; - value = this.dictionary.GetOrAdd(key, valueFactory); - InvalidateCache(); + /// + public bool IsReadOnly => false; - return value; - } + /// + public void Add(TKey key, TValue value) + { + ((IDictionary)_dictionary).Add(key, value); + InvalidateCache(); + } - /// - /// Attempts to add the specified key and value. - /// - /// The key of the element to add. - /// The value of the element to add. The value can be a null reference (Nothing - /// in Visual Basic) for reference types. - /// true if the key/value pair was added successfully; otherwise, false. - public bool TryAdd(TKey key, TValue value) + /// + /// Adds a key/value pair to the if the key does not exist. + /// + /// The key of the element to add. + /// The function used to generate a value for the key + /// The value for the key. This will be either the existing value for the key if the key is already in the dictionary, or the new value if the key was not in the dictionary. + public TValue GetOrAdd(TKey key, Func valueFactory) + { + if (GetReadDictionary().TryGetValue(key, out var value)) { - if (this.dictionary.TryAdd(key, value)) - { - this.InvalidateCache(); - return true; - } - - return false; + return value; } - /// - public bool ContainsKey(TKey key) => this.GetReadDictionary().ContainsKey(key); + value = _dictionary.GetOrAdd(key, valueFactory); + InvalidateCache(); - /// - public bool Remove(TKey key) + return value; + } + + /// + /// Attempts to add the specified key and value. + /// + /// The key of the element to add. + /// The value of the element to add. The value can be a null reference (Nothing + /// in Visual Basic) for reference types. + /// true if the key/value pair was added successfully; otherwise, false. + public bool TryAdd(TKey key, TValue value) + { + if (_dictionary.TryAdd(key, value)) { - var result = ((IDictionary)this.dictionary).Remove(key); - if (result) this.InvalidateCache(); - return result; + InvalidateCache(); + return true; } -#if NET6_0_OR_GREATER - /// - public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value) => this.GetReadDictionary().TryGetValue(key, out value); -#else - /// - public bool TryGetValue(TKey key, out TValue value) => this.GetReadDictionary().TryGetValue(key, out value); + return false; + } + + /// + public bool ContainsKey(TKey key) => GetReadDictionary().ContainsKey(key); + + /// + public bool Remove(TKey key) + { + var result = ((IDictionary)_dictionary).Remove(key); + if (result) InvalidateCache(); + return result; + } -#endif + /// + public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value) => GetReadDictionary().TryGetValue(key, out value); - /// - public TValue this[TKey key] + /// + public TValue this[TKey key] + { + get => GetReadDictionary()[key]; + set { - get => this.GetReadDictionary()[key]; - set - { - this.dictionary[key] = value; - this.InvalidateCache(); - } + _dictionary[key] = value; + InvalidateCache(); } + } - /// - public ICollection Keys => this.GetReadDictionary().Keys; + /// + public ICollection Keys => GetReadDictionary().Keys; - /// - public ICollection Values => this.GetReadDictionary().Values; + /// + public ICollection Values => GetReadDictionary().Values; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private IDictionary GetReadDictionary() => this.readCache ?? this.GetWithoutCache(); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private IDictionary GetReadDictionary() => _readCache ?? GetWithoutCache(); - private IDictionary GetWithoutCache() + private IDictionary GetWithoutCache() + { + // If the dictionary was recently modified or the cache is being recomputed, return the dictionary directly. + if (Interlocked.Increment(ref _cacheMissReads) < _cacheMissesBeforeCaching) { - // If the dictionary was recently modified or the cache is being recomputed, return the dictionary directly. - if (Interlocked.Increment(ref this.cacheMissReads) < CacheMissesBeforeCaching) - { - return this.dictionary; - } - - // Recompute the cache if too many cache misses have occurred. - this.cacheMissReads = 0; - return this.readCache = new Dictionary(this.dictionary, this.comparer); + return _dictionary; } - private void InvalidateCache() - { - this.cacheMissReads = 0; - this.readCache = null; - } + // Recompute the cache if too many cache misses have occurred. + _cacheMissReads = 0; + return _readCache = new Dictionary(_dictionary, _comparer); + } + + private void InvalidateCache() + { + _cacheMissReads = 0; + _readCache = null; } } diff --git a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/ContextFactoryRepositoryBaseOfT.cs b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/ContextFactoryRepositoryBaseOfT.cs index 961505a3..7aec7b8f 100644 --- a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/ContextFactoryRepositoryBaseOfT.cs +++ b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/ContextFactoryRepositoryBaseOfT.cs @@ -1,234 +1,228 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore; - -namespace Ardalis.Specification.EntityFrameworkCore +using Microsoft.EntityFrameworkCore; + +namespace Ardalis.Specification.EntityFrameworkCore; + +public abstract class ContextFactoryRepositoryBaseOfT : IRepositoryBase + where TEntity : class + where TContext : DbContext { - public abstract class ContextFactoryRepositoryBaseOfT : IRepositoryBase - where TEntity : class - where TContext : DbContext - { - private IDbContextFactory dbContextFactory; - private ISpecificationEvaluator specificationEvaluator; - - public ContextFactoryRepositoryBaseOfT(IDbContextFactory dbContextFactory) - : this(dbContextFactory, SpecificationEvaluator.Default) - { - } - - public ContextFactoryRepositoryBaseOfT(IDbContextFactory dbContextFactory, - ISpecificationEvaluator specificationEvaluator) - { - this.dbContextFactory = dbContextFactory; - this.specificationEvaluator = specificationEvaluator; - } - - /// - public async Task GetByIdAsync(TId id, CancellationToken cancellationToken = default) where TId : notnull - { - await using var dbContext = this.dbContextFactory.CreateDbContext(); - return await dbContext.Set().FindAsync(new object[] { id }, cancellationToken: cancellationToken); - } - - /// - public async Task GetBySpecAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - await using var dbContext = this.dbContextFactory.CreateDbContext(); - return await ApplySpecification(specification, dbContext).FirstOrDefaultAsync(cancellationToken); - } - - /// - public async Task GetBySpecAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - await using var dbContext = this.dbContextFactory.CreateDbContext(); - return await ApplySpecification(specification, dbContext).FirstOrDefaultAsync(cancellationToken); - } - - /// - public async Task FirstOrDefaultAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - await using var dbContext = this.dbContextFactory.CreateDbContext(); - return await ApplySpecification(specification, dbContext).FirstOrDefaultAsync(cancellationToken); - } - - /// - public async Task FirstOrDefaultAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - await using var dbContext = this.dbContextFactory.CreateDbContext(); - return await ApplySpecification(specification, dbContext).FirstOrDefaultAsync(cancellationToken); - } - - /// - public async Task SingleOrDefaultAsync(ISingleResultSpecification specification, CancellationToken cancellationToken = default) - { - await using var dbContext = this.dbContextFactory.CreateDbContext(); - return await ApplySpecification(specification, dbContext).FirstOrDefaultAsync(cancellationToken); - } - - /// - public async Task SingleOrDefaultAsync(ISingleResultSpecification specification, - CancellationToken cancellationToken = default) - { - await using var dbContext = this.dbContextFactory.CreateDbContext(); - return await ApplySpecification(specification, dbContext).FirstOrDefaultAsync(cancellationToken); - } - - /// - public async Task> ListAsync(CancellationToken cancellationToken = default) - { - await using var dbContext = this.dbContextFactory.CreateDbContext(); - return await dbContext.Set().ToListAsync(cancellationToken); - } - - /// - public async Task> ListAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - await using var dbContext = this.dbContextFactory.CreateDbContext(); - var queryResult = await ApplySpecification(specification, dbContext).ToListAsync(cancellationToken); - - return specification.PostProcessingAction == null ? queryResult : specification.PostProcessingAction(queryResult).ToList(); - } - - /// - public async Task> ListAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - await using var dbContext = this.dbContextFactory.CreateDbContext(); - var queryResult = await ApplySpecification(specification, dbContext).ToListAsync(cancellationToken); - - return specification.PostProcessingAction == null ? queryResult : specification.PostProcessingAction(queryResult).ToList(); - } - - /// - public async Task CountAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - await using var dbContext = this.dbContextFactory.CreateDbContext(); - return await ApplySpecification(specification, dbContext, true).CountAsync(cancellationToken); - } - - /// - public async Task CountAsync(CancellationToken cancellationToken = default) - { - await using var dbContext = this.dbContextFactory.CreateDbContext(); - return await dbContext.Set().CountAsync(cancellationToken); - } - - /// - public async Task AnyAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - await using var dbContext = this.dbContextFactory.CreateDbContext(); - return await ApplySpecification(specification, dbContext, true).AnyAsync(cancellationToken); - } - - /// - public async Task AnyAsync(CancellationToken cancellationToken = default) - { - await using var dbContext = this.dbContextFactory.CreateDbContext(); - return await dbContext.Set().AnyAsync(cancellationToken); - } - - /// - public IAsyncEnumerable AsAsyncEnumerable(ISpecification specification) - { - using var dbContext = this.dbContextFactory.CreateDbContext(); - return ApplySpecification(specification, dbContext).AsAsyncEnumerable(); - } - - /// - public async Task AddAsync(TEntity entity, CancellationToken cancellationToken = default) - { - await using var dbContext = this.dbContextFactory.CreateDbContext(); - dbContext.Set().Add(entity); - - await SaveChangesAsync(dbContext, cancellationToken); - - return entity; - } - - /// - public async Task> AddRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) - { - await using var dbContext = this.dbContextFactory.CreateDbContext(); - dbContext.Set().AddRange(entities); - - await SaveChangesAsync(dbContext, cancellationToken); - - return entities; - } - - /// - public async Task UpdateAsync(TEntity entity, CancellationToken cancellationToken = default) - { - await using var dbContext = this.dbContextFactory.CreateDbContext(); - dbContext.Set().Update(entity); - - await SaveChangesAsync(dbContext, cancellationToken); - } - - /// - public async Task UpdateRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) - { - await using var dbContext = this.dbContextFactory.CreateDbContext(); - dbContext.Set().UpdateRange(entities); - - await SaveChangesAsync(dbContext, cancellationToken); - } - - /// - public async Task DeleteAsync(TEntity entity, CancellationToken cancellationToken = default) - { - await using var dbContext = this.dbContextFactory.CreateDbContext(); - dbContext.Set().Remove(entity); - - await SaveChangesAsync(dbContext, cancellationToken); - } - - /// - public async Task DeleteRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) - { - await using var dbContext = this.dbContextFactory.CreateDbContext(); - dbContext.Set().RemoveRange(entities); - - await SaveChangesAsync(dbContext, cancellationToken); - } - - /// - public async Task SaveChangesAsync(CancellationToken cancellationToken = default) - { - throw new InvalidOperationException(); - } - - public async Task SaveChangesAsync(TContext dbContext, CancellationToken cancellationToken = default) - { - return await dbContext.SaveChangesAsync(cancellationToken); - } - - /// - /// Filters the entities of , to those that match the encapsulated query logic of the - /// . - /// - /// The encapsulated query logic. - /// The filtered entities as an . - protected virtual IQueryable ApplySpecification(ISpecification specification, TContext dbContext, bool evaluateCriteriaOnly = false) - { - return specificationEvaluator.GetQuery(dbContext.Set().AsQueryable(), specification, evaluateCriteriaOnly); - } - - /// - /// Filters all entities of , that matches the encapsulated query logic of the - /// , from the database. - /// - /// Projects each entity into a new form, being . - /// - /// - /// The type of the value returned by the projection. - /// The encapsulated query logic. - /// The filtered projected entities as an . - protected virtual IQueryable ApplySpecification(ISpecification specification, TContext dbContext) - { - return specificationEvaluator.GetQuery(dbContext.Set().AsQueryable(), specification); - } + private readonly IDbContextFactory _dbContextFactory; + private readonly ISpecificationEvaluator _specificationEvaluator; + + public ContextFactoryRepositoryBaseOfT(IDbContextFactory dbContextFactory) + : this(dbContextFactory, SpecificationEvaluator.Default) + { + } + + public ContextFactoryRepositoryBaseOfT(IDbContextFactory dbContextFactory, + ISpecificationEvaluator specificationEvaluator) + { + _dbContextFactory = dbContextFactory; + _specificationEvaluator = specificationEvaluator; + } + + /// + public async Task GetByIdAsync(TId id, CancellationToken cancellationToken = default) where TId : notnull + { + await using var dbContext = _dbContextFactory.CreateDbContext(); + return await dbContext.Set().FindAsync(new object[] { id }, cancellationToken: cancellationToken); + } + + /// + public async Task GetBySpecAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + await using var dbContext = _dbContextFactory.CreateDbContext(); + return await ApplySpecification(specification, dbContext).FirstOrDefaultAsync(cancellationToken); + } + + /// + public async Task GetBySpecAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + await using var dbContext = _dbContextFactory.CreateDbContext(); + return await ApplySpecification(specification, dbContext).FirstOrDefaultAsync(cancellationToken); + } + + /// + public async Task FirstOrDefaultAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + await using var dbContext = _dbContextFactory.CreateDbContext(); + return await ApplySpecification(specification, dbContext).FirstOrDefaultAsync(cancellationToken); + } + + /// + public async Task FirstOrDefaultAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + await using var dbContext = _dbContextFactory.CreateDbContext(); + return await ApplySpecification(specification, dbContext).FirstOrDefaultAsync(cancellationToken); + } + + /// + public async Task SingleOrDefaultAsync(ISingleResultSpecification specification, CancellationToken cancellationToken = default) + { + await using var dbContext = _dbContextFactory.CreateDbContext(); + return await ApplySpecification(specification, dbContext).FirstOrDefaultAsync(cancellationToken); + } + + /// + public async Task SingleOrDefaultAsync(ISingleResultSpecification specification, + CancellationToken cancellationToken = default) + { + await using var dbContext = _dbContextFactory.CreateDbContext(); + return await ApplySpecification(specification, dbContext).FirstOrDefaultAsync(cancellationToken); + } + + /// + public async Task> ListAsync(CancellationToken cancellationToken = default) + { + await using var dbContext = _dbContextFactory.CreateDbContext(); + return await dbContext.Set().ToListAsync(cancellationToken); + } + + /// + public async Task> ListAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + await using var dbContext = _dbContextFactory.CreateDbContext(); + var queryResult = await ApplySpecification(specification, dbContext).ToListAsync(cancellationToken); + + return specification.PostProcessingAction == null ? queryResult : specification.PostProcessingAction(queryResult).ToList(); + } + + /// + public async Task> ListAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + await using var dbContext = _dbContextFactory.CreateDbContext(); + var queryResult = await ApplySpecification(specification, dbContext).ToListAsync(cancellationToken); + + return specification.PostProcessingAction == null ? queryResult : specification.PostProcessingAction(queryResult).ToList(); + } + + /// + public async Task CountAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + await using var dbContext = _dbContextFactory.CreateDbContext(); + return await ApplySpecification(specification, dbContext, true).CountAsync(cancellationToken); + } + + /// + public async Task CountAsync(CancellationToken cancellationToken = default) + { + await using var dbContext = _dbContextFactory.CreateDbContext(); + return await dbContext.Set().CountAsync(cancellationToken); + } + + /// + public async Task AnyAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + await using var dbContext = _dbContextFactory.CreateDbContext(); + return await ApplySpecification(specification, dbContext, true).AnyAsync(cancellationToken); + } + + /// + public async Task AnyAsync(CancellationToken cancellationToken = default) + { + await using var dbContext = _dbContextFactory.CreateDbContext(); + return await dbContext.Set().AnyAsync(cancellationToken); + } + + /// + public IAsyncEnumerable AsAsyncEnumerable(ISpecification specification) + { + using var dbContext = _dbContextFactory.CreateDbContext(); + return ApplySpecification(specification, dbContext).AsAsyncEnumerable(); + } + + /// + public async Task AddAsync(TEntity entity, CancellationToken cancellationToken = default) + { + await using var dbContext = _dbContextFactory.CreateDbContext(); + dbContext.Set().Add(entity); + + await SaveChangesAsync(dbContext, cancellationToken); + + return entity; + } + + /// + public async Task> AddRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) + { + await using var dbContext = _dbContextFactory.CreateDbContext(); + dbContext.Set().AddRange(entities); + + await SaveChangesAsync(dbContext, cancellationToken); + + return entities; + } + + /// + public async Task UpdateAsync(TEntity entity, CancellationToken cancellationToken = default) + { + await using var dbContext = _dbContextFactory.CreateDbContext(); + dbContext.Set().Update(entity); + + await SaveChangesAsync(dbContext, cancellationToken); + } + + /// + public async Task UpdateRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) + { + await using var dbContext = _dbContextFactory.CreateDbContext(); + dbContext.Set().UpdateRange(entities); + + await SaveChangesAsync(dbContext, cancellationToken); + } + + /// + public async Task DeleteAsync(TEntity entity, CancellationToken cancellationToken = default) + { + await using var dbContext = _dbContextFactory.CreateDbContext(); + dbContext.Set().Remove(entity); + + await SaveChangesAsync(dbContext, cancellationToken); + } + + /// + public async Task DeleteRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) + { + await using var dbContext = _dbContextFactory.CreateDbContext(); + dbContext.Set().RemoveRange(entities); + + await SaveChangesAsync(dbContext, cancellationToken); + } + + /// + public Task SaveChangesAsync(CancellationToken cancellationToken = default) + { + throw new InvalidOperationException(); + } + + public async Task SaveChangesAsync(TContext dbContext, CancellationToken cancellationToken = default) + { + return await dbContext.SaveChangesAsync(cancellationToken); + } + + /// + /// Filters the entities of , to those that match the encapsulated query logic of the + /// . + /// + /// The encapsulated query logic. + /// The filtered entities as an . + protected virtual IQueryable ApplySpecification(ISpecification specification, TContext dbContext, bool evaluateCriteriaOnly = false) + { + return _specificationEvaluator.GetQuery(dbContext.Set().AsQueryable(), specification, evaluateCriteriaOnly); + } + + /// + /// Filters all entities of , that matches the encapsulated query logic of the + /// , from the database. + /// + /// Projects each entity into a new form, being . + /// + /// + /// The type of the value returned by the projection. + /// The encapsulated query logic. + /// The filtered projected entities as an . + protected virtual IQueryable ApplySpecification(ISpecification specification, TContext dbContext) + { + return _specificationEvaluator.GetQuery(dbContext.Set().AsQueryable(), specification); } } diff --git a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/EFRepositoryFactory.cs b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/EFRepositoryFactory.cs index dba7bc13..8f5c970e 100644 --- a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/EFRepositoryFactory.cs +++ b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/EFRepositoryFactory.cs @@ -1,36 +1,34 @@ -using System; -using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; -namespace Ardalis.Specification.EntityFrameworkCore +namespace Ardalis.Specification.EntityFrameworkCore; + +/// +/// +/// +/// The Interface of the repository created by this Factory +/// +/// The Concrete implementation of the repository interface to create +/// +/// The DbContext derived class to support the concrete repository +public class EFRepositoryFactory : IRepositoryFactory + where TConcreteRepository : TRepository + where TContext : DbContext { + private readonly IDbContextFactory _dbContextFactory; + /// - /// + /// Initialises a new instance of the EFRepositoryFactory /// - /// The Interface of the repository created by this Factory - /// - /// The Concrete implementation of the repository interface to create - /// - /// The DbContext derived class to support the concrete repository - public class EFRepositoryFactory : IRepositoryFactory - where TConcreteRepository : TRepository - where TContext : DbContext + /// The IDbContextFactory to use to generate the TContext + public EFRepositoryFactory(IDbContextFactory dbContextFactory) { - private IDbContextFactory dbContextFactory; - - /// - /// Initialises a new instance of the EFRepositoryFactory - /// - /// The IDbContextFactory to use to generate the TContext - public EFRepositoryFactory(IDbContextFactory dbContextFactory) - { - this.dbContextFactory = dbContextFactory; - } + _dbContextFactory = dbContextFactory; + } - /// - public TRepository CreateRepository() - { - var args = new object[] { dbContextFactory.CreateDbContext() }; - return (TRepository)Activator.CreateInstance(typeof(TConcreteRepository), args); - } + /// + public TRepository CreateRepository() + { + var args = new object[] { _dbContextFactory.CreateDbContext() }; + return (TRepository)Activator.CreateInstance(typeof(TConcreteRepository), args)!; } } diff --git a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/AsNoTrackingEvaluator.cs b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/AsNoTrackingEvaluator.cs index b2352cd3..561b62c8 100644 --- a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/AsNoTrackingEvaluator.cs +++ b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/AsNoTrackingEvaluator.cs @@ -1,26 +1,21 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; -namespace Ardalis.Specification.EntityFrameworkCore +namespace Ardalis.Specification.EntityFrameworkCore; + +public class AsNoTrackingEvaluator : IEvaluator { - public class AsNoTrackingEvaluator : IEvaluator - { - private AsNoTrackingEvaluator() { } - public static AsNoTrackingEvaluator Instance { get; } = new AsNoTrackingEvaluator(); + private AsNoTrackingEvaluator() { } + public static AsNoTrackingEvaluator Instance { get; } = new AsNoTrackingEvaluator(); - public bool IsCriteriaEvaluator { get; } = true; + public bool IsCriteriaEvaluator { get; } = true; - public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class + public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class + { + if (specification.AsNoTracking) { - if (specification.AsNoTracking) - { - query = query.AsNoTracking(); - } - - return query; + query = query.AsNoTracking(); } + + return query; } } diff --git a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/AsNoTrackingWithIdentityResolutionEvaluator.cs b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/AsNoTrackingWithIdentityResolutionEvaluator.cs index ccf87541..c2292e66 100644 --- a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/AsNoTrackingWithIdentityResolutionEvaluator.cs +++ b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/AsNoTrackingWithIdentityResolutionEvaluator.cs @@ -1,28 +1,21 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; -namespace Ardalis.Specification.EntityFrameworkCore +namespace Ardalis.Specification.EntityFrameworkCore; + +public class AsNoTrackingWithIdentityResolutionEvaluator : IEvaluator { -#if !NETSTANDARD2_0 - public class AsNoTrackingWithIdentityResolutionEvaluator : IEvaluator - { - private AsNoTrackingWithIdentityResolutionEvaluator() { } - public static AsNoTrackingWithIdentityResolutionEvaluator Instance { get; } = new AsNoTrackingWithIdentityResolutionEvaluator(); + private AsNoTrackingWithIdentityResolutionEvaluator() { } + public static AsNoTrackingWithIdentityResolutionEvaluator Instance { get; } = new AsNoTrackingWithIdentityResolutionEvaluator(); - public bool IsCriteriaEvaluator { get; } = true; + public bool IsCriteriaEvaluator { get; } = true; - public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class + public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class + { + if (specification.AsNoTrackingWithIdentityResolution) { - if (specification.AsNoTrackingWithIdentityResolution) - { - query = query.AsNoTrackingWithIdentityResolution(); - } - - return query; + query = query.AsNoTrackingWithIdentityResolution(); } + + return query; } -#endif } diff --git a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/AsSplitQueryEvaluator.cs b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/AsSplitQueryEvaluator.cs index e2ff7e3c..5b2943bb 100644 --- a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/AsSplitQueryEvaluator.cs +++ b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/AsSplitQueryEvaluator.cs @@ -1,28 +1,21 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; -namespace Ardalis.Specification.EntityFrameworkCore +namespace Ardalis.Specification.EntityFrameworkCore; + +public class AsSplitQueryEvaluator : IEvaluator { -#if !NETSTANDARD2_0 - public class AsSplitQueryEvaluator : IEvaluator - { - private AsSplitQueryEvaluator() { } - public static AsSplitQueryEvaluator Instance { get; } = new AsSplitQueryEvaluator(); + private AsSplitQueryEvaluator() { } + public static AsSplitQueryEvaluator Instance { get; } = new AsSplitQueryEvaluator(); - public bool IsCriteriaEvaluator { get; } = true; + public bool IsCriteriaEvaluator { get; } = true; - public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class + public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class + { + if (specification.AsSplitQuery) { - if (specification.AsSplitQuery) - { - query = query.AsSplitQuery(); - } - - return query; + query = query.AsSplitQuery(); } + + return query; } -#endif } diff --git a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/AsTrackingEvaluator.cs b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/AsTrackingEvaluator.cs index f67273b2..91af9528 100644 --- a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/AsTrackingEvaluator.cs +++ b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/AsTrackingEvaluator.cs @@ -1,26 +1,21 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; -namespace Ardalis.Specification.EntityFrameworkCore +namespace Ardalis.Specification.EntityFrameworkCore; + +public class AsTrackingEvaluator : IEvaluator { - public class AsTrackingEvaluator : IEvaluator - { - private AsTrackingEvaluator() { } - public static AsTrackingEvaluator Instance { get; } = new AsTrackingEvaluator(); + private AsTrackingEvaluator() { } + public static AsTrackingEvaluator Instance { get; } = new AsTrackingEvaluator(); - public bool IsCriteriaEvaluator { get; } = true; + public bool IsCriteriaEvaluator { get; } = true; - public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class + public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class + { + if (specification.AsTracking) { - if (specification.AsTracking) - { - query = query.AsTracking(); - } - - return query; + query = query.AsTracking(); } + + return query; } } diff --git a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/IgnoreQueryFiltersEvaluator.cs b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/IgnoreQueryFiltersEvaluator.cs index b03b5128..d122bbfd 100644 --- a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/IgnoreQueryFiltersEvaluator.cs +++ b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/IgnoreQueryFiltersEvaluator.cs @@ -1,27 +1,25 @@ -using System.Linq; -using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; -namespace Ardalis.Specification.EntityFrameworkCore +namespace Ardalis.Specification.EntityFrameworkCore; + +/// +/// This evaluator applies EF Core's IgnoreQueryFilters feature to a given query +/// See: https://docs.microsoft.com/en-us/ef/core/querying/filters +/// +public class IgnoreQueryFiltersEvaluator : IEvaluator { - /// - /// This evaluator applies EF Core's IgnoreQueryFilters feature to a given query - /// See: https://docs.microsoft.com/en-us/ef/core/querying/filters - /// - public class IgnoreQueryFiltersEvaluator : IEvaluator - { - private IgnoreQueryFiltersEvaluator() { } - public static IgnoreQueryFiltersEvaluator Instance { get; } = new IgnoreQueryFiltersEvaluator(); + private IgnoreQueryFiltersEvaluator() { } + public static IgnoreQueryFiltersEvaluator Instance { get; } = new IgnoreQueryFiltersEvaluator(); - public bool IsCriteriaEvaluator { get; } = true; + public bool IsCriteriaEvaluator { get; } = true; - public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class + public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class + { + if (specification.IgnoreQueryFilters) { - if (specification.IgnoreQueryFilters) - { - query = query.IgnoreQueryFilters(); - } - - return query; + query = query.IgnoreQueryFilters(); } + + return query; } } diff --git a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/IncludeEvaluator.cs b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/IncludeEvaluator.cs index e63a0bd3..bb54814b 100644 --- a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/IncludeEvaluator.cs +++ b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/IncludeEvaluator.cs @@ -1,193 +1,188 @@ -using System; -using System.Collections.Generic; -using System.Linq; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Query; using System.Linq.Expressions; using System.Reflection; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Query; -namespace Ardalis.Specification.EntityFrameworkCore +namespace Ardalis.Specification.EntityFrameworkCore; + +public class IncludeEvaluator : IEvaluator { - public class IncludeEvaluator : IEvaluator + private static readonly MethodInfo _includeMethodInfo = typeof(EntityFrameworkQueryableExtensions) + .GetTypeInfo().GetDeclaredMethods(nameof(EntityFrameworkQueryableExtensions.Include)) + .Single(mi => mi.GetGenericArguments().Length == 2 + && mi.GetParameters()[0].ParameterType.GetGenericTypeDefinition() == typeof(IQueryable<>) + && mi.GetParameters()[1].ParameterType.GetGenericTypeDefinition() == typeof(Expression<>)); + + private static readonly MethodInfo _thenIncludeAfterReferenceMethodInfo + = typeof(EntityFrameworkQueryableExtensions) + .GetTypeInfo().GetDeclaredMethods(nameof(EntityFrameworkQueryableExtensions.ThenInclude)) + .Single(mi => mi.GetGenericArguments().Length == 3 + && mi.GetParameters()[0].ParameterType.GenericTypeArguments[1].IsGenericParameter + && mi.GetParameters()[0].ParameterType.GetGenericTypeDefinition() == typeof(IIncludableQueryable<,>) + && mi.GetParameters()[1].ParameterType.GetGenericTypeDefinition() == typeof(Expression<>)); + + private static readonly MethodInfo _thenIncludeAfterEnumerableMethodInfo + = typeof(EntityFrameworkQueryableExtensions) + .GetTypeInfo().GetDeclaredMethods(nameof(EntityFrameworkQueryableExtensions.ThenInclude)) + .Where(mi => mi.GetGenericArguments().Length == 3) + .Single( + mi => + { + var typeInfo = mi.GetParameters()[0].ParameterType.GenericTypeArguments[1]; + + return typeInfo.IsGenericType + && typeInfo.GetGenericTypeDefinition() == typeof(IEnumerable<>) + && mi.GetParameters()[0].ParameterType.GetGenericTypeDefinition() == typeof(IIncludableQueryable<,>) + && mi.GetParameters()[1].ParameterType.GetGenericTypeDefinition() == typeof(Expression<>); + }); + + private static readonly CachedReadConcurrentDictionary<(Type EntityType, Type PropertyType, Type? PreviousPropertyType), Lazy>> _delegatesCache = new(); + + private readonly bool _cacheEnabled; + + private IncludeEvaluator(bool cacheEnabled) { - private static readonly MethodInfo IncludeMethodInfo = typeof(EntityFrameworkQueryableExtensions) - .GetTypeInfo().GetDeclaredMethods(nameof(EntityFrameworkQueryableExtensions.Include)) - .Single(mi => mi.GetGenericArguments().Length == 2 - && mi.GetParameters()[0].ParameterType.GetGenericTypeDefinition() == typeof(IQueryable<>) - && mi.GetParameters()[1].ParameterType.GetGenericTypeDefinition() == typeof(Expression<>)); - - private static readonly MethodInfo ThenIncludeAfterReferenceMethodInfo - = typeof(EntityFrameworkQueryableExtensions) - .GetTypeInfo().GetDeclaredMethods(nameof(EntityFrameworkQueryableExtensions.ThenInclude)) - .Single(mi => mi.GetGenericArguments().Length == 3 - && mi.GetParameters()[0].ParameterType.GenericTypeArguments[1].IsGenericParameter - && mi.GetParameters()[0].ParameterType.GetGenericTypeDefinition() == typeof(IIncludableQueryable<,>) - && mi.GetParameters()[1].ParameterType.GetGenericTypeDefinition() == typeof(Expression<>)); - - private static readonly MethodInfo ThenIncludeAfterEnumerableMethodInfo - = typeof(EntityFrameworkQueryableExtensions) - .GetTypeInfo().GetDeclaredMethods(nameof(EntityFrameworkQueryableExtensions.ThenInclude)) - .Where(mi => mi.GetGenericArguments().Length == 3) - .Single( - mi => - { - var typeInfo = mi.GetParameters()[0].ParameterType.GenericTypeArguments[1]; - - return typeInfo.IsGenericType - && typeInfo.GetGenericTypeDefinition() == typeof(IEnumerable<>) - && mi.GetParameters()[0].ParameterType.GetGenericTypeDefinition() == typeof(IIncludableQueryable<,>) - && mi.GetParameters()[1].ParameterType.GetGenericTypeDefinition() == typeof(Expression<>); - }); - - private static readonly CachedReadConcurrentDictionary<(Type EntityType, Type PropertyType, Type? PreviousPropertyType), Lazy>> DelegatesCache = - new CachedReadConcurrentDictionary<(Type EntityType, Type PropertyType, Type? PreviousPropertyType), Lazy>>(); - - private readonly bool cacheEnabled; - - private IncludeEvaluator(bool cacheEnabled) - { - this.cacheEnabled = cacheEnabled; - } + _cacheEnabled = cacheEnabled; + } - /// - /// instance without any additional features. - /// - public static IncludeEvaluator Default { get; } = new IncludeEvaluator(false); + /// + /// instance without any additional features. + /// + public static IncludeEvaluator Default { get; } = new IncludeEvaluator(false); - /// - /// instance with caching to provide better performance. - /// - public static IncludeEvaluator Cached { get; } = new IncludeEvaluator(true); + /// + /// instance with caching to provide better performance. + /// + public static IncludeEvaluator Cached { get; } = new IncludeEvaluator(true); - public bool IsCriteriaEvaluator => false; + public bool IsCriteriaEvaluator => false; - public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class + public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class + { + foreach (var includeString in specification.IncludeStrings) { - foreach (var includeString in specification.IncludeStrings) + query = query.Include(includeString); + } + + foreach (var includeInfo in specification.IncludeExpressions) + { + if (includeInfo.Type == IncludeTypeEnum.Include) { - query = query.Include(includeString); + query = BuildInclude(query, includeInfo); } - - foreach (var includeInfo in specification.IncludeExpressions) + else if (includeInfo.Type == IncludeTypeEnum.ThenInclude) { - if (includeInfo.Type == IncludeTypeEnum.Include) - { - query = this.BuildInclude(query, includeInfo); - } - else if (includeInfo.Type == IncludeTypeEnum.ThenInclude) - { - query = this.BuildThenInclude(query, includeInfo); - } + query = BuildThenInclude(query, includeInfo); } - - return query; } - private IQueryable BuildInclude(IQueryable query, IncludeExpressionInfo includeInfo) + return query; + } + + private IQueryable BuildInclude(IQueryable query, IncludeExpressionInfo includeInfo) + { + _ = includeInfo ?? throw new ArgumentNullException(nameof(includeInfo)); + + if (!_cacheEnabled) { - _ = includeInfo ?? throw new ArgumentNullException(nameof(includeInfo)); + var result = _includeMethodInfo.MakeGenericMethod(includeInfo.EntityType, includeInfo.PropertyType).Invoke(null, new object[] { query, includeInfo.LambdaExpression }); - if (!this.cacheEnabled) - { - var result = IncludeMethodInfo.MakeGenericMethod(includeInfo.EntityType, includeInfo.PropertyType).Invoke(null, new object[] { query, includeInfo.LambdaExpression }); + _ = result ?? throw new TargetException(); - _ = result ?? throw new TargetException(); + return (IQueryable)result; + } - return (IQueryable)result; - } + var include = _delegatesCache.GetOrAdd((includeInfo.EntityType, includeInfo.PropertyType, null), CreateIncludeDelegate).Value; - var include = DelegatesCache.GetOrAdd((includeInfo.EntityType, includeInfo.PropertyType, null), CreateIncludeDelegate).Value; + return (IQueryable)include(query, includeInfo.LambdaExpression); + } - return (IQueryable)include(query, includeInfo.LambdaExpression); - } + private IQueryable BuildThenInclude(IQueryable query, IncludeExpressionInfo includeInfo) + { + _ = includeInfo ?? throw new ArgumentNullException(nameof(includeInfo)); + _ = includeInfo.PreviousPropertyType ?? throw new ArgumentNullException(nameof(includeInfo.PreviousPropertyType)); - private IQueryable BuildThenInclude(IQueryable query, IncludeExpressionInfo includeInfo) + if (!_cacheEnabled) { - _ = includeInfo ?? throw new ArgumentNullException(nameof(includeInfo)); - _ = includeInfo.PreviousPropertyType ?? throw new ArgumentNullException(nameof(includeInfo.PreviousPropertyType)); + var result = (IsGenericEnumerable(includeInfo.PreviousPropertyType, out var previousPropertyType) + ? _thenIncludeAfterEnumerableMethodInfo + : _thenIncludeAfterReferenceMethodInfo).MakeGenericMethod(includeInfo.EntityType, previousPropertyType, includeInfo.PropertyType) + .Invoke(null, new object[] { query, includeInfo.LambdaExpression, }); - if (!this.cacheEnabled) - { - var result = (IsGenericEnumerable(includeInfo.PreviousPropertyType, out var previousPropertyType) - ? ThenIncludeAfterEnumerableMethodInfo - : ThenIncludeAfterReferenceMethodInfo).MakeGenericMethod(includeInfo.EntityType, previousPropertyType, includeInfo.PropertyType) - .Invoke(null, new object[] { query, includeInfo.LambdaExpression, }); + _ = result ?? throw new TargetException(); - _ = result ?? throw new TargetException(); + return (IQueryable)result; + } - return (IQueryable)result; - } + var thenInclude = _delegatesCache.GetOrAdd((includeInfo.EntityType, includeInfo.PropertyType, includeInfo.PreviousPropertyType), CreateThenIncludeDelegate).Value; - var thenInclude = DelegatesCache.GetOrAdd((includeInfo.EntityType, includeInfo.PropertyType, includeInfo.PreviousPropertyType), CreateThenIncludeDelegate).Value; + return (IQueryable)thenInclude(query, includeInfo.LambdaExpression); + } - return (IQueryable)thenInclude(query, includeInfo.LambdaExpression); - } + // (source, selector) => EntityFrameworkQueryableExtensions.Include((IQueryable)source, (Expression>)selector); + private static Lazy> CreateIncludeDelegate((Type EntityType, Type PropertyType, Type? PreviousPropertyType) cacheKey) + => new(() => + { + var concreteInclude = _includeMethodInfo.MakeGenericMethod(cacheKey.EntityType, cacheKey.PropertyType); + var sourceParameter = Expression.Parameter(typeof(IQueryable)); + var selectorParameter = Expression.Parameter(typeof(LambdaExpression)); + + var call = Expression.Call( + concreteInclude, + Expression.Convert(sourceParameter, typeof(IQueryable<>).MakeGenericType(cacheKey.EntityType)), + Expression.Convert(selectorParameter, typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(cacheKey.EntityType, cacheKey.PropertyType)))); + + var lambda = Expression.Lambda>(call, sourceParameter, selectorParameter); + + return lambda.Compile(); + }); + + // ((source, selector) => + // EntityFrameworkQueryableExtensions.ThenInclude( + // (IIncludableQueryable)source, + // (Expression>)selector); + // (source, selector) => + // EntityFrameworkQueryableExtensions.ThenInclude( + // (IIncludableQueryable>)source, + // (Expression>)selector); + private static Lazy> CreateThenIncludeDelegate((Type EntityType, Type PropertyType, Type? PreviousPropertyType) cacheKey) + => new(() => + { + _ = cacheKey.PreviousPropertyType ?? throw new ArgumentNullException(nameof(cacheKey.PreviousPropertyType)); - // (source, selector) => EntityFrameworkQueryableExtensions.Include((IQueryable)source, (Expression>)selector); - private static Lazy> CreateIncludeDelegate((Type EntityType, Type PropertyType, Type? PreviousPropertyType) cacheKey) - => new Lazy>(() => - { - var concreteInclude = IncludeMethodInfo.MakeGenericMethod(cacheKey.EntityType, cacheKey.PropertyType); - var sourceParameter = Expression.Parameter(typeof(IQueryable)); - var selectorParameter = Expression.Parameter(typeof(LambdaExpression)); - - var call = Expression.Call( - concreteInclude, - Expression.Convert(sourceParameter, typeof(IQueryable<>).MakeGenericType(cacheKey.EntityType)), - Expression.Convert(selectorParameter, typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(cacheKey.EntityType, cacheKey.PropertyType)))); - - var lambda = Expression.Lambda>(call, sourceParameter, selectorParameter); - - return lambda.Compile(); - }); - - // ((source, selector) => - // EntityFrameworkQueryableExtensions.ThenInclude( - // (IIncludableQueryable)source, - // (Expression>)selector); - // (source, selector) => - // EntityFrameworkQueryableExtensions.ThenInclude( - // (IIncludableQueryable>)source, - // (Expression>)selector); - private static Lazy> CreateThenIncludeDelegate((Type EntityType, Type PropertyType, Type? PreviousPropertyType) cacheKey) - => new Lazy>(() => + var thenIncludeInfo = _thenIncludeAfterReferenceMethodInfo; + if (IsGenericEnumerable(cacheKey.PreviousPropertyType, out var previousPropertyType)) { - _ = cacheKey.PreviousPropertyType ?? throw new ArgumentNullException(nameof(cacheKey.PreviousPropertyType)); - - MethodInfo thenIncludeInfo = ThenIncludeAfterReferenceMethodInfo; - if (IsGenericEnumerable(cacheKey.PreviousPropertyType, out var previousPropertyType)) - { - thenIncludeInfo = ThenIncludeAfterEnumerableMethodInfo; - } + thenIncludeInfo = _thenIncludeAfterEnumerableMethodInfo; + } - var concreteThenInclude = thenIncludeInfo.MakeGenericMethod(cacheKey.EntityType, previousPropertyType, cacheKey.PropertyType); - var sourceParameter = Expression.Parameter(typeof(IQueryable)); - var selectorParameter = Expression.Parameter(typeof(LambdaExpression)); + var concreteThenInclude = thenIncludeInfo.MakeGenericMethod(cacheKey.EntityType, previousPropertyType, cacheKey.PropertyType); + var sourceParameter = Expression.Parameter(typeof(IQueryable)); + var selectorParameter = Expression.Parameter(typeof(LambdaExpression)); - var call = Expression.Call( - concreteThenInclude, - Expression.Convert( - sourceParameter, - typeof(IIncludableQueryable<,>).MakeGenericType(cacheKey.EntityType, cacheKey.PreviousPropertyType)), // cacheKey.PreviousPropertyType must be exact type, not generic type argument - Expression.Convert(selectorParameter, typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(previousPropertyType, cacheKey.PropertyType)))); + var call = Expression.Call( + concreteThenInclude, + Expression.Convert( + sourceParameter, + typeof(IIncludableQueryable<,>).MakeGenericType(cacheKey.EntityType, cacheKey.PreviousPropertyType)), // cacheKey.PreviousPropertyType must be exact type, not generic type argument + Expression.Convert(selectorParameter, typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(previousPropertyType, cacheKey.PropertyType)))); - var lambda = Expression.Lambda>(call, sourceParameter, selectorParameter); + var lambda = Expression.Lambda>(call, sourceParameter, selectorParameter); - return lambda.Compile(); - }); + return lambda.Compile(); + }); - private static bool IsGenericEnumerable(Type type, out Type propertyType) + private static bool IsGenericEnumerable(Type type, out Type propertyType) + { + if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable<>)) { - if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable<>)) - { - propertyType = type.GenericTypeArguments[0]; + propertyType = type.GenericTypeArguments[0]; - return true; - } + return true; + } - propertyType = type; + propertyType = type; - return false; - } + return false; } } diff --git a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/SearchEvaluator.cs b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/SearchEvaluator.cs index 121d4319..3f0960fc 100644 --- a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/SearchEvaluator.cs +++ b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/SearchEvaluator.cs @@ -1,22 +1,19 @@ -using System.Linq; +namespace Ardalis.Specification.EntityFrameworkCore; -namespace Ardalis.Specification.EntityFrameworkCore +public class SearchEvaluator : IEvaluator { - public class SearchEvaluator : IEvaluator - { - private SearchEvaluator() { } - public static SearchEvaluator Instance { get; } = new SearchEvaluator(); + private SearchEvaluator() { } + public static SearchEvaluator Instance { get; } = new SearchEvaluator(); - public bool IsCriteriaEvaluator { get; } = true; + public bool IsCriteriaEvaluator { get; } = true; - public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class + public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class + { + foreach (var searchCriteria in specification.SearchCriterias.GroupBy(x => x.SearchGroup)) { - foreach (var searchCriteria in specification.SearchCriterias.GroupBy(x => x.SearchGroup)) - { - query = query.Search(searchCriteria); - } - - return query; + query = query.Search(searchCriteria); } + + 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 559e5786..5ebb6763 100644 --- a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/SpecificationEvaluator.cs +++ b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/SpecificationEvaluator.cs @@ -1,74 +1,69 @@ -using System; -using System.Collections.Generic; -using System.Linq; +namespace Ardalis.Specification.EntityFrameworkCore; -namespace Ardalis.Specification.EntityFrameworkCore +/// +public class SpecificationEvaluator : ISpecificationEvaluator { - /// - public class SpecificationEvaluator : ISpecificationEvaluator - { - // Will use singleton for default configuration. Yet, it can be instantiated if necessary, with default or provided evaluators. - /// - /// instance with default evaluators and without any additional features enabled. - /// - public static SpecificationEvaluator Default { get; } = new SpecificationEvaluator(); - - /// - /// instance with default evaluators and enabled caching. - /// - public static SpecificationEvaluator Cached { get; } = new SpecificationEvaluator(true); + // Will use singleton for default configuration. Yet, it can be instantiated if necessary, with default or provided evaluators. + /// + /// instance with default evaluators and without any additional features enabled. + /// + public static SpecificationEvaluator Default { get; } = new SpecificationEvaluator(); - protected List Evaluators { get; } = new List(); + /// + /// instance with default evaluators and enabled caching. + /// + public static SpecificationEvaluator Cached { get; } = new SpecificationEvaluator(true); - public SpecificationEvaluator(bool cacheEnabled = false) - { - this.Evaluators.AddRange(new IEvaluator[] - { - WhereEvaluator.Instance, - SearchEvaluator.Instance, - cacheEnabled ? IncludeEvaluator.Cached : IncludeEvaluator.Default, - OrderEvaluator.Instance, - PaginationEvaluator.Instance, - AsNoTrackingEvaluator.Instance, - AsNoTrackingWithIdentityResolutionEvaluator.Instance, - AsTrackingEvaluator.Instance, - IgnoreQueryFiltersEvaluator.Instance, - AsSplitQueryEvaluator.Instance - }); - } + protected List Evaluators { get; } = new List(); - public SpecificationEvaluator(IEnumerable evaluators) + public SpecificationEvaluator(bool cacheEnabled = false) + { + Evaluators.AddRange(new IEvaluator[] { - this.Evaluators.AddRange(evaluators); - } + WhereEvaluator.Instance, + SearchEvaluator.Instance, + cacheEnabled ? IncludeEvaluator.Cached : IncludeEvaluator.Default, + OrderEvaluator.Instance, + PaginationEvaluator.Instance, + AsNoTrackingEvaluator.Instance, + AsNoTrackingWithIdentityResolutionEvaluator.Instance, + AsTrackingEvaluator.Instance, + IgnoreQueryFiltersEvaluator.Instance, + AsSplitQueryEvaluator.Instance + }); + } - /// - public virtual IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class - { - if (specification is null) throw new ArgumentNullException("Specification is required"); - if (specification.Selector is null && specification.SelectorMany is null) throw new SelectorNotFoundException(); - if (specification.Selector != null && specification.SelectorMany != null) throw new ConcurrentSelectorsException(); + public SpecificationEvaluator(IEnumerable evaluators) + { + Evaluators.AddRange(evaluators); + } - query = GetQuery(query, (ISpecification)specification); + /// + public virtual IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class + { + if (specification is null) throw new ArgumentNullException(nameof(specification)); + if (specification.Selector is null && specification.SelectorMany is null) throw new SelectorNotFoundException(); + if (specification.Selector is not null && specification.SelectorMany is not null) throw new ConcurrentSelectorsException(); - return specification.Selector is not null - ? query.Select(specification.Selector) - : query.SelectMany(specification.SelectorMany!); - } + query = GetQuery(query, (ISpecification)specification); - /// - public virtual IQueryable GetQuery(IQueryable query, ISpecification specification, bool evaluateCriteriaOnly = false) where T : class - { - if (specification is null) throw new ArgumentNullException("Specification is required"); + return specification.Selector is not null + ? query.Select(specification.Selector) + : query.SelectMany(specification.SelectorMany!); + } - var evaluators = evaluateCriteriaOnly ? this.Evaluators.Where(x => x.IsCriteriaEvaluator) : this.Evaluators; + /// + public virtual IQueryable GetQuery(IQueryable query, ISpecification specification, bool evaluateCriteriaOnly = false) where T : class + { + if (specification is null) throw new ArgumentNullException(nameof(specification)); - foreach (var evaluator in evaluators) - { - query = evaluator.GetQuery(query, specification); - } + var evaluators = evaluateCriteriaOnly ? Evaluators.Where(x => x.IsCriteriaEvaluator) : Evaluators; - return query; + foreach (var evaluator in evaluators) + { + query = evaluator.GetQuery(query, specification); } + + return query; } } diff --git a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Extensions/DbSetExtensions.cs b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Extensions/DbSetExtensions.cs index ed13f61a..c54b7ddb 100644 --- a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Extensions/DbSetExtensions.cs +++ b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Extensions/DbSetExtensions.cs @@ -1,57 +1,52 @@ -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; -namespace Ardalis.Specification.EntityFrameworkCore +namespace Ardalis.Specification.EntityFrameworkCore; + +public static class DbSetExtensions { - public static class DbSetExtensions + public static async Task> ToListAsync( + this DbSet source, + ISpecification specification, + CancellationToken cancellationToken = default) + where TSource : class { - public static async Task> ToListAsync( - this DbSet source, - ISpecification specification, - CancellationToken cancellationToken = default) - where TSource : class - { - var result = await SpecificationEvaluator.Default.GetQuery(source, specification).ToListAsync(cancellationToken); + var result = await SpecificationEvaluator.Default.GetQuery(source, specification).ToListAsync(cancellationToken); - return specification.PostProcessingAction == null - ? result - : specification.PostProcessingAction(result).ToList(); - } + return specification.PostProcessingAction == null + ? result + : specification.PostProcessingAction(result).ToList(); + } - public static async Task> ToEnumerableAsync( - this DbSet source, - ISpecification specification, - CancellationToken cancellationToken = default) - where TSource : class - { - var result = await SpecificationEvaluator.Default.GetQuery(source, specification).ToListAsync(cancellationToken); + public static async Task> ToEnumerableAsync( + this DbSet source, + ISpecification specification, + CancellationToken cancellationToken = default) + where TSource : class + { + var result = await SpecificationEvaluator.Default.GetQuery(source, specification).ToListAsync(cancellationToken); - return specification.PostProcessingAction == null - ? result - : specification.PostProcessingAction(result); - } + return specification.PostProcessingAction == null + ? result + : specification.PostProcessingAction(result); + } - public static IQueryable WithSpecification( - this IQueryable source, - ISpecification specification, - ISpecificationEvaluator? evaluator = null) - where TSource : class - { - evaluator = evaluator ?? SpecificationEvaluator.Default; - return evaluator.GetQuery(source, specification); - } + public static IQueryable WithSpecification( + this IQueryable source, + ISpecification specification, + ISpecificationEvaluator? evaluator = null) + where TSource : class + { + evaluator ??= SpecificationEvaluator.Default; + return evaluator.GetQuery(source, specification); + } - public static IQueryable WithSpecification( - this IQueryable source, - ISpecification specification, - ISpecificationEvaluator? evaluator = null) - where TSource : class - { - evaluator = evaluator ?? SpecificationEvaluator.Default; - return evaluator.GetQuery(source, specification); - } + public static IQueryable WithSpecification( + this IQueryable source, + ISpecification specification, + ISpecificationEvaluator? evaluator = null) + where TSource : class + { + evaluator ??= SpecificationEvaluator.Default; + return evaluator.GetQuery(source, specification); } } diff --git a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Extensions/ParameterReplacerVisitor.cs b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Extensions/ParameterReplacerVisitor.cs index 9c2e7b09..655bc721 100644 --- a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Extensions/ParameterReplacerVisitor.cs +++ b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Extensions/ParameterReplacerVisitor.cs @@ -1,33 +1,21 @@ using System.Linq.Expressions; -namespace Ardalis.Specification.EntityFrameworkCore +namespace Ardalis.Specification.EntityFrameworkCore; + +internal class ParameterReplacerVisitor : ExpressionVisitor { - internal class ParameterReplacerVisitor : ExpressionVisitor - { - private readonly Expression newExpression; - private readonly ParameterExpression oldParameter; + private readonly Expression _newExpression; + private readonly ParameterExpression _oldParameter; - private ParameterReplacerVisitor(ParameterExpression oldParameter, Expression newExpression) - { - this.oldParameter = oldParameter; - this.newExpression = newExpression; - } + private ParameterReplacerVisitor(ParameterExpression oldParameter, Expression newExpression) + { + _oldParameter = oldParameter; + _newExpression = newExpression; + } - internal static Expression Replace(Expression expression, ParameterExpression oldParameter, Expression newExpression) - { - return new ParameterReplacerVisitor(oldParameter, newExpression).Visit(expression); - } + internal static Expression Replace(Expression expression, ParameterExpression oldParameter, Expression newExpression) + => new ParameterReplacerVisitor(oldParameter, newExpression).Visit(expression); - protected override Expression VisitParameter(ParameterExpression p) - { - if (p == oldParameter) - { - return newExpression; - } - else - { - return p; - } - } - } + protected override Expression VisitParameter(ParameterExpression p) + => p == _oldParameter ? _newExpression : p; } diff --git a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Extensions/SearchExtension.cs b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Extensions/SearchExtension.cs index 51ca508b..381f5faf 100644 --- a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Extensions/SearchExtension.cs +++ b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Extensions/SearchExtension.cs @@ -1,63 +1,59 @@ -using System; -using System.Collections.Generic; +using Microsoft.EntityFrameworkCore; using System.Data; -using System.Linq; using System.Linq.Expressions; using System.Reflection; -using Microsoft.EntityFrameworkCore; -namespace Ardalis.Specification.EntityFrameworkCore +namespace Ardalis.Specification.EntityFrameworkCore; + +public static class SearchExtension { - public static class SearchExtension + private static readonly MethodInfo _likeMethodInfo = typeof(DbFunctionsExtensions) + .GetMethod(nameof(DbFunctionsExtensions.Like), new Type[] { typeof(DbFunctions), typeof(string), typeof(string) }) + ?? throw new TargetException("The EF.Functions.Like not found"); + + private static readonly MemberExpression _functions = Expression.Property(null, typeof(EF).GetProperty(nameof(EF.Functions)) + ?? throw new TargetException("The EF.Functions not found!")); + + /// + /// Filters by applying an 'SQL LIKE' operation to it. + /// + /// The type being queried against. + /// The sequence of + /// + /// + /// Selector, the property to apply the SQL LIKE against. + /// SearchTerm, the value to use for the SQL LIKE. + /// + /// + /// + public static IQueryable Search(this IQueryable source, IEnumerable> criterias) { - private static readonly MethodInfo LikeMethodInfo = typeof(DbFunctionsExtensions) - .GetMethod(nameof(DbFunctionsExtensions.Like), new Type[] { typeof(DbFunctions), typeof(string), typeof(string) }) - ?? throw new TargetException("The EF.Functions.Like not found"); - - private static readonly MemberExpression Functions = Expression.Property(null, typeof(EF).GetProperty(nameof(EF.Functions)) - ?? throw new TargetException("The EF.Functions not found!")); - - /// - /// Filters by applying an 'SQL LIKE' operation to it. - /// - /// The type being queried against. - /// The sequence of - /// - /// - /// Selector, the property to apply the SQL LIKE against. - /// SearchTerm, the value to use for the SQL LIKE. - /// - /// - /// - public static IQueryable Search(this IQueryable source, IEnumerable> criterias) - { - Expression? expr = null; - var parameter = Expression.Parameter(typeof(T), "x"); - - foreach (var criteria in criterias) - { - if (string.IsNullOrEmpty(criteria.SearchTerm)) - continue; + Expression? expr = null; + var parameter = Expression.Parameter(typeof(T), "x"); - var propertySelector = ParameterReplacerVisitor.Replace(criteria.Selector, criteria.Selector.Parameters[0], parameter) as LambdaExpression; - _ = propertySelector ?? throw new InvalidExpressionException(); + foreach (var criteria in criterias) + { + if (string.IsNullOrEmpty(criteria.SearchTerm)) + continue; - // Create a closure - var searchTermAsExpression = ((Expression>)(() => criteria.SearchTerm)).Body; + var propertySelector = ParameterReplacerVisitor.Replace(criteria.Selector, criteria.Selector.Parameters[0], parameter) as LambdaExpression; + _ = propertySelector ?? throw new InvalidExpressionException(); - var likeExpression = Expression.Call( - null, - LikeMethodInfo, - Functions, - propertySelector.Body, - searchTermAsExpression); + // Create a closure + var searchTermAsExpression = ((Expression>)(() => criteria.SearchTerm)).Body; - expr = expr == null ? (Expression)likeExpression : Expression.OrElse(expr, likeExpression); - } + var likeExpression = Expression.Call( + null, + _likeMethodInfo, + _functions, + propertySelector.Body, + searchTermAsExpression); - return expr == null - ? source - : source.Where(Expression.Lambda>(expr, parameter)); + expr = expr == null ? (Expression)likeExpression : Expression.OrElse(expr, likeExpression); } + + return expr == null + ? source + : source.Where(Expression.Lambda>(expr, parameter)); } } diff --git a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/IRepositoryFactory.cs b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/IRepositoryFactory.cs index 257b9d27..eaafd90d 100644 --- a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/IRepositoryFactory.cs +++ b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/IRepositoryFactory.cs @@ -1,18 +1,17 @@ -namespace Ardalis.Specification.EntityFrameworkCore +namespace Ardalis.Specification.EntityFrameworkCore; + +/// +/// Generates new instances of to encapsulate the 'Unit of Work' pattern +/// in scenarios where injected types may be long-lived (e.g. Blazor) +/// +/// +/// The Interface of the Repository to be generated. +/// +public interface IRepositoryFactory { /// - /// Generates new instances of to encapsulate the 'Unit of Work' pattern - /// in scenarios where injected types may be long-lived (e.g. Blazor) + /// Generates a new repository instance /// - /// - /// The Interface of the Repository to be generated. - /// - public interface IRepositoryFactory - { - /// - /// Generates a new repository instance - /// - /// The generated repository instance - public TRepository CreateRepository(); - } + /// The generated repository instance + public TRepository CreateRepository(); } diff --git a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/RepositoryBaseOfT.cs b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/RepositoryBaseOfT.cs index 564b6dab..1d94bda8 100644 --- a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/RepositoryBaseOfT.cs +++ b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/RepositoryBaseOfT.cs @@ -1,208 +1,202 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore; - -namespace Ardalis.Specification.EntityFrameworkCore +using Microsoft.EntityFrameworkCore; + +namespace Ardalis.Specification.EntityFrameworkCore; + +/// +public abstract class RepositoryBase : IRepositoryBase where T : class { + private readonly DbContext _dbContext; + private readonly ISpecificationEvaluator _specificationEvaluator; + + public RepositoryBase(DbContext dbContext) + : this(dbContext, SpecificationEvaluator.Default) + { + } + + /// + public RepositoryBase(DbContext dbContext, ISpecificationEvaluator specificationEvaluator) + { + _dbContext = dbContext; + _specificationEvaluator = specificationEvaluator; + } + + /// + public virtual async Task AddAsync(T entity, CancellationToken cancellationToken = default) + { + _dbContext.Set().Add(entity); + + await SaveChangesAsync(cancellationToken); + + return entity; + } + + /// + public virtual async Task> AddRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) + { + _dbContext.Set().AddRange(entities); + + await SaveChangesAsync(cancellationToken); + + return entities; + } + + /// + public virtual async Task UpdateAsync(T entity, CancellationToken cancellationToken = default) + { + _dbContext.Set().Update(entity); + + await SaveChangesAsync(cancellationToken); + } + + /// + public virtual async Task UpdateRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) + { + _dbContext.Set().UpdateRange(entities); + + await SaveChangesAsync(cancellationToken); + } + + /// + public virtual async Task DeleteAsync(T entity, CancellationToken cancellationToken = default) + { + _dbContext.Set().Remove(entity); + + await SaveChangesAsync(cancellationToken); + } + + /// + public virtual async Task DeleteRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) + { + _dbContext.Set().RemoveRange(entities); + + await SaveChangesAsync(cancellationToken); + } + /// - public abstract class RepositoryBase : IRepositoryBase where T : class - { - private readonly DbContext dbContext; - private readonly ISpecificationEvaluator specificationEvaluator; - - public RepositoryBase(DbContext dbContext) - : this(dbContext, SpecificationEvaluator.Default) - { - } - - /// - public RepositoryBase(DbContext dbContext, ISpecificationEvaluator specificationEvaluator) - { - this.dbContext = dbContext; - this.specificationEvaluator = specificationEvaluator; - } - - /// - public virtual async Task AddAsync(T entity, CancellationToken cancellationToken = default) - { - dbContext.Set().Add(entity); - - await SaveChangesAsync(cancellationToken); - - return entity; - } - - /// - public virtual async Task> AddRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) - { - dbContext.Set().AddRange(entities); - - await SaveChangesAsync(cancellationToken); - - return entities; - } - - /// - public virtual async Task UpdateAsync(T entity, CancellationToken cancellationToken = default) - { - dbContext.Set().Update(entity); - - await SaveChangesAsync(cancellationToken); - } - - /// - public virtual async Task UpdateRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) - { - dbContext.Set().UpdateRange(entities); - - await SaveChangesAsync(cancellationToken); - } - - /// - public virtual async Task DeleteAsync(T entity, CancellationToken cancellationToken = default) - { - dbContext.Set().Remove(entity); - - await SaveChangesAsync(cancellationToken); - } - - /// - public virtual async Task DeleteRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) - { - dbContext.Set().RemoveRange(entities); - - await SaveChangesAsync(cancellationToken); - } - - /// - public virtual async Task SaveChangesAsync(CancellationToken cancellationToken = default) - { - return await dbContext.SaveChangesAsync(cancellationToken); - } - - /// - public virtual async Task GetByIdAsync(TId id, CancellationToken cancellationToken = default) where TId : notnull - { - return await dbContext.Set().FindAsync(new object[] { id }, cancellationToken: cancellationToken); - } - - /// - [Obsolete] - public virtual async Task GetBySpecAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - return await ApplySpecification(specification).FirstOrDefaultAsync(cancellationToken); - } - - /// - [Obsolete] - public virtual async Task GetBySpecAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - return await ApplySpecification(specification).FirstOrDefaultAsync(cancellationToken); - } - - /// - public virtual async Task FirstOrDefaultAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - return await ApplySpecification(specification).FirstOrDefaultAsync(cancellationToken); - } - - /// - public virtual async Task FirstOrDefaultAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - return await ApplySpecification(specification).FirstOrDefaultAsync(cancellationToken); - } - - /// - public virtual async Task SingleOrDefaultAsync(ISingleResultSpecification specification, CancellationToken cancellationToken = default) - { - return await ApplySpecification(specification).SingleOrDefaultAsync(cancellationToken); - } - - /// - public virtual async Task SingleOrDefaultAsync(ISingleResultSpecification specification, CancellationToken cancellationToken = default) - { - return await ApplySpecification(specification).SingleOrDefaultAsync(cancellationToken); - } - - /// - public virtual async Task> ListAsync(CancellationToken cancellationToken = default) - { - return await dbContext.Set().ToListAsync(cancellationToken); - } - - /// - public virtual async Task> ListAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - var queryResult = await ApplySpecification(specification).ToListAsync(cancellationToken); - - return specification.PostProcessingAction == null ? queryResult : specification.PostProcessingAction(queryResult).ToList(); - } - - /// - public virtual async Task> ListAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - var queryResult = await ApplySpecification(specification).ToListAsync(cancellationToken); - - return specification.PostProcessingAction == null ? queryResult : specification.PostProcessingAction(queryResult).ToList(); - } - - /// - public virtual async Task CountAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - return await ApplySpecification(specification, true).CountAsync(cancellationToken); - } - - /// - public virtual async Task CountAsync(CancellationToken cancellationToken = default) - { - return await dbContext.Set().CountAsync(cancellationToken); - } - - /// - public virtual async Task AnyAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - return await ApplySpecification(specification, true).AnyAsync(cancellationToken); - } - - /// - public virtual async Task AnyAsync(CancellationToken cancellationToken = default) - { - return await dbContext.Set().AnyAsync(cancellationToken); - } - - /// - public virtual IAsyncEnumerable AsAsyncEnumerable(ISpecification specification) - { - return ApplySpecification(specification).AsAsyncEnumerable(); - } - - /// - /// Filters the entities of , to those that match the encapsulated query logic of the - /// . - /// - /// The encapsulated query logic. - /// The filtered entities as an . - protected virtual IQueryable ApplySpecification(ISpecification specification, bool evaluateCriteriaOnly = false) - { - return specificationEvaluator.GetQuery(dbContext.Set().AsQueryable(), specification, evaluateCriteriaOnly); - } - - /// - /// Filters all entities of , that matches the encapsulated query logic of the - /// , from the database. - /// - /// Projects each entity into a new form, being . - /// - /// - /// The type of the value returned by the projection. - /// The encapsulated query logic. - /// The filtered projected entities as an . - protected virtual IQueryable ApplySpecification(ISpecification specification) - { - return specificationEvaluator.GetQuery(dbContext.Set().AsQueryable(), specification); - } + public virtual async Task SaveChangesAsync(CancellationToken cancellationToken = default) + { + return await _dbContext.SaveChangesAsync(cancellationToken); + } + + /// + public virtual async Task GetByIdAsync(TId id, CancellationToken cancellationToken = default) where TId : notnull + { + return await _dbContext.Set().FindAsync(new object[] { id }, cancellationToken: cancellationToken); + } + + /// + [Obsolete] + public virtual async Task GetBySpecAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + return await ApplySpecification(specification).FirstOrDefaultAsync(cancellationToken); + } + + /// + [Obsolete] + public virtual async Task GetBySpecAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + return await ApplySpecification(specification).FirstOrDefaultAsync(cancellationToken); + } + + /// + public virtual async Task FirstOrDefaultAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + return await ApplySpecification(specification).FirstOrDefaultAsync(cancellationToken); + } + + /// + public virtual async Task FirstOrDefaultAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + return await ApplySpecification(specification).FirstOrDefaultAsync(cancellationToken); + } + + /// + public virtual async Task SingleOrDefaultAsync(ISingleResultSpecification specification, CancellationToken cancellationToken = default) + { + return await ApplySpecification(specification).SingleOrDefaultAsync(cancellationToken); + } + + /// + public virtual async Task SingleOrDefaultAsync(ISingleResultSpecification specification, CancellationToken cancellationToken = default) + { + return await ApplySpecification(specification).SingleOrDefaultAsync(cancellationToken); + } + + /// + public virtual async Task> ListAsync(CancellationToken cancellationToken = default) + { + return await _dbContext.Set().ToListAsync(cancellationToken); + } + + /// + public virtual async Task> ListAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + var queryResult = await ApplySpecification(specification).ToListAsync(cancellationToken); + + return specification.PostProcessingAction == null ? queryResult : specification.PostProcessingAction(queryResult).ToList(); + } + + /// + public virtual async Task> ListAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + var queryResult = await ApplySpecification(specification).ToListAsync(cancellationToken); + + return specification.PostProcessingAction == null ? queryResult : specification.PostProcessingAction(queryResult).ToList(); + } + + /// + public virtual async Task CountAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + return await ApplySpecification(specification, true).CountAsync(cancellationToken); + } + + /// + public virtual async Task CountAsync(CancellationToken cancellationToken = default) + { + return await _dbContext.Set().CountAsync(cancellationToken); + } + + /// + public virtual async Task AnyAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + return await ApplySpecification(specification, true).AnyAsync(cancellationToken); + } + + /// + public virtual async Task AnyAsync(CancellationToken cancellationToken = default) + { + return await _dbContext.Set().AnyAsync(cancellationToken); + } + + /// + public virtual IAsyncEnumerable AsAsyncEnumerable(ISpecification specification) + { + return ApplySpecification(specification).AsAsyncEnumerable(); + } + + /// + /// Filters the entities of , to those that match the encapsulated query logic of the + /// . + /// + /// The encapsulated query logic. + /// The filtered entities as an . + protected virtual IQueryable ApplySpecification(ISpecification specification, bool evaluateCriteriaOnly = false) + { + return _specificationEvaluator.GetQuery(_dbContext.Set().AsQueryable(), specification, evaluateCriteriaOnly); + } + + /// + /// Filters all entities of , that matches the encapsulated query logic of the + /// , from the database. + /// + /// Projects each entity into a new form, being . + /// + /// + /// The type of the value returned by the projection. + /// The encapsulated query logic. + /// The filtered projected entities as an . + protected virtual IQueryable ApplySpecification(ISpecification specification) + { + return _specificationEvaluator.GetQuery(_dbContext.Set().AsQueryable(), specification); } } diff --git a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests.csproj b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests.csproj index 939e1773..6dd63555 100644 --- a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests.csproj +++ b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests.csproj @@ -1,27 +1,27 @@  - net6.0 + net7.0 + 11.0 + disable + enable false - 9.0 - enable - - - runtime; build; native; contentfiles; analyzers + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -32,4 +32,8 @@ + + 1701;1702;1591;1573;0612 + + diff --git a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/ContextFactoryRepositoryBaseOfTTests.cs b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/ContextFactoryRepositoryBaseOfTTests.cs index c98c4c4e..b49110ef 100644 --- a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/ContextFactoryRepositoryBaseOfTTests.cs +++ b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/ContextFactoryRepositoryBaseOfTTests.cs @@ -1,150 +1,146 @@ -using System; -using System.Linq; -using System.Threading.Tasks; -using Ardalis.Specification.EntityFrameworkCore.IntegrationTests.Fixture; +using Ardalis.Specification.EntityFrameworkCore.IntegrationTests.Fixture; using Ardalis.Specification.UnitTests.Fixture.Entities; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Xunit; -namespace Ardalis.Specification.EntityFrameworkCore.IntegrationTests +namespace Ardalis.Specification.EntityFrameworkCore.IntegrationTests; + +public class ContextFactoryRepositoryBaseOfTTests : IClassFixture { - public class ContextFactoryRepositoryBaseOfTTests : IClassFixture - { - protected TestDbContext dbContext; - protected IServiceProvider serviceProvider; - protected ContextFactoryRepository repository; + protected TestDbContext dbContext; + protected IServiceProvider serviceProvider; + protected ContextFactoryRepository repository; - public ContextFactoryRepositoryBaseOfTTests(SharedDatabaseFixture fixture) - { - dbContext = fixture.CreateContext(); + public ContextFactoryRepositoryBaseOfTTests(SharedDatabaseFixture fixture) + { + dbContext = fixture.CreateContext(); - serviceProvider = new ServiceCollection() - .AddDbContextFactory((builder => builder.UseSqlServer(fixture.Connection)), - ServiceLifetime.Transient).BuildServiceProvider(); + serviceProvider = new ServiceCollection() + .AddDbContextFactory((builder => builder.UseSqlServer(fixture.Connection)), + ServiceLifetime.Transient).BuildServiceProvider(); - var contextFactory = serviceProvider.GetService>(); - repository = new ContextFactoryRepository(contextFactory); - } + var contextFactory = serviceProvider.GetService>(); + repository = new ContextFactoryRepository(contextFactory); + } - [Fact] - public async Task Saves_new_entity() - { - var country = await dbContext.Countries.FirstOrDefaultAsync(); + [Fact] + public async Task Saves_new_entity() + { + var country = await dbContext.Countries.FirstOrDefaultAsync(); - var company = new Company(); - company.Name = "Test save new company name"; - company.CountryId = country.Id; + var company = new Company(); + company.Name = "Test save new company name"; + company.CountryId = country.Id; - await repository.AddAsync(company); - Assert.NotEqual(0, company.Id); - } + await repository.AddAsync(company); + Assert.NotEqual(0, company.Id); + } - [Fact] - public async Task Updates_existing_entity() - { - var country = await dbContext.Countries.FirstOrDefaultAsync(); + [Fact] + public async Task Updates_existing_entity() + { + var country = await dbContext.Countries.FirstOrDefaultAsync(); - var company = new Company { Name = "Test update existing company name", CountryId = country.Id }; - await repository.AddAsync(company); + var company = new Company { Name = "Test update existing company name", CountryId = country.Id }; + await repository.AddAsync(company); - var existingCompany = await repository.GetByIdAsync(company.Id); - existingCompany.Name = "Updated company name"; - await repository.UpdateAsync(existingCompany); + var existingCompany = await repository.GetByIdAsync(company.Id); + existingCompany.Name = "Updated company name"; + await repository.UpdateAsync(existingCompany); - var validationCompany = await dbContext.Companies.FirstOrDefaultAsync(x => x.Id == company.Id); - Assert.Equal(validationCompany.Name, existingCompany.Name); - } + var validationCompany = await dbContext.Companies.FirstOrDefaultAsync(x => x.Id == company.Id); + Assert.Equal(validationCompany.Name, existingCompany.Name); + } - [Fact] - public async Task Updates_existing_entity_across_context_instances() - { - var contextFactory = serviceProvider.GetService>(); - var companyRetrievalRepository = new ContextFactoryRepository(contextFactory); - var companySaveRepository = new ContextFactoryRepository(contextFactory); + [Fact] + public async Task Updates_existing_entity_across_context_instances() + { + var contextFactory = serviceProvider.GetService>(); + var companyRetrievalRepository = new ContextFactoryRepository(contextFactory); + var companySaveRepository = new ContextFactoryRepository(contextFactory); - var country = await dbContext.Countries.FirstOrDefaultAsync(); + var country = await dbContext.Countries.FirstOrDefaultAsync(); - var company = new Company { Name = "Test update existing company name", CountryId = country.Id }; - await repository.AddAsync(company); + var company = new Company { Name = "Test update existing company name", CountryId = country.Id }; + await repository.AddAsync(company); - var existingCompany = await companyRetrievalRepository.GetByIdAsync(company.Id); - existingCompany.Name = "Updated company name"; - await companySaveRepository.UpdateAsync(existingCompany); + var existingCompany = await companyRetrievalRepository.GetByIdAsync(company.Id); + existingCompany.Name = "Updated company name"; + await companySaveRepository.UpdateAsync(existingCompany); - var validationCompany = await dbContext.Companies.FirstOrDefaultAsync(x => x.Id == company.Id); - Assert.Equal(validationCompany.Name, existingCompany.Name); - } + var validationCompany = await dbContext.Companies.FirstOrDefaultAsync(x => x.Id == company.Id); + Assert.Equal(validationCompany.Name, existingCompany.Name); + } - [Fact] - public async Task Updates_graph() - { - var country = await dbContext.Countries.FirstOrDefaultAsync(); + [Fact] + public async Task Updates_graph() + { + var country = await dbContext.Countries.FirstOrDefaultAsync(); - var company = new Company { Name = "Test update graph", CountryId = country.Id }; - var store = new Store { Name = "Store Number 1" }; - company.Stores.Add(store); + var company = new Company { Name = "Test update graph", CountryId = country.Id }; + var store = new Store { Name = "Store Number 1" }; + company.Stores.Add(store); - await repository.AddAsync(company); + await repository.AddAsync(company); - var spec = new GetCompanyWithStoresSpec(company.Id); - var existingCompany = await repository.FirstOrDefaultAsync(spec); - existingCompany.Name = "Updated company name"; - var existingStore = existingCompany.Stores.FirstOrDefault(); - existingStore.Name = "Updated Store Name"; + var spec = new GetCompanyWithStoresSpec(company.Id); + var existingCompany = await repository.FirstOrDefaultAsync(spec); + existingCompany.Name = "Updated company name"; + var existingStore = existingCompany.Stores.FirstOrDefault(); + existingStore.Name = "Updated Store Name"; - await repository.UpdateAsync(existingCompany); + await repository.UpdateAsync(existingCompany); - var validationCompany = await dbContext.Companies.FirstOrDefaultAsync(x => x.Id == company.Id); - Assert.Equal(validationCompany.Name, existingCompany.Name); + var validationCompany = await dbContext.Companies.FirstOrDefaultAsync(x => x.Id == company.Id); + Assert.Equal(validationCompany.Name, existingCompany.Name); - var validationStore = await dbContext.Stores.FirstOrDefaultAsync(x => x.CompanyId == company.Id); - Assert.Equal(validationStore.Name, existingStore.Name); - } + var validationStore = await dbContext.Stores.FirstOrDefaultAsync(x => x.CompanyId == company.Id); + Assert.Equal(validationStore.Name, existingStore.Name); + } - [Fact] - public async Task Updates_graph_across_context_instances() - { - var contextFactory = serviceProvider.GetService>(); - var companyRetrievalRepository = new ContextFactoryRepository(contextFactory); - var companySaveRepository = new ContextFactoryRepository(contextFactory); + [Fact] + public async Task Updates_graph_across_context_instances() + { + var contextFactory = serviceProvider.GetService>(); + var companyRetrievalRepository = new ContextFactoryRepository(contextFactory); + var companySaveRepository = new ContextFactoryRepository(contextFactory); - var country = await dbContext.Countries.FirstOrDefaultAsync(); + var country = await dbContext.Countries.FirstOrDefaultAsync(); - var company = new Company { Name = "Test update graph", CountryId = country.Id }; - var store = new Store { Name = "Store Number 1" }; - company.Stores.Add(store); + var company = new Company { Name = "Test update graph", CountryId = country.Id }; + var store = new Store { Name = "Store Number 1" }; + company.Stores.Add(store); - await repository.AddAsync(company); + await repository.AddAsync(company); - var spec = new GetCompanyWithStoresSpec(company.Id); - var existingCompany = await companyRetrievalRepository.FirstOrDefaultAsync(spec); - existingCompany.Name = "Updated company name"; - var existingStore = existingCompany.Stores.FirstOrDefault(); - existingStore.Name = "Updated Store Name"; + var spec = new GetCompanyWithStoresSpec(company.Id); + var existingCompany = await companyRetrievalRepository.FirstOrDefaultAsync(spec); + existingCompany.Name = "Updated company name"; + var existingStore = existingCompany.Stores.FirstOrDefault(); + existingStore.Name = "Updated Store Name"; - await companySaveRepository.UpdateAsync(existingCompany); + await companySaveRepository.UpdateAsync(existingCompany); - var validationCompany = await dbContext.Companies.FirstOrDefaultAsync(x => x.Id == company.Id); - Assert.Equal(validationCompany.Name, existingCompany.Name); + var validationCompany = await dbContext.Companies.FirstOrDefaultAsync(x => x.Id == company.Id); + Assert.Equal(validationCompany.Name, existingCompany.Name); - var validationStore = await dbContext.Stores.FirstOrDefaultAsync(x => x.CompanyId == company.Id); - Assert.Equal(validationStore.Name, existingStore.Name); - } + var validationStore = await dbContext.Stores.FirstOrDefaultAsync(x => x.CompanyId == company.Id); + Assert.Equal(validationStore.Name, existingStore.Name); + } - [Fact] - public async Task Deletes_entity() - { - var country = await dbContext.Countries.FirstOrDefaultAsync(); + [Fact] + public async Task Deletes_entity() + { + var country = await dbContext.Countries.FirstOrDefaultAsync(); - var company = new Company { Name = "Test update graph", CountryId = country.Id }; - await repository.AddAsync(company); + var company = new Company { Name = "Test update graph", CountryId = country.Id }; + await repository.AddAsync(company); - var companyId = company.Id; - await repository.DeleteAsync(company); + var companyId = company.Id; + await repository.DeleteAsync(company); - var validationCompany = await repository.GetByIdAsync(companyId); - Assert.Null(validationCompany); - } + var validationCompany = await repository.GetByIdAsync(companyId); + Assert.Null(validationCompany); } } diff --git a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/EFRepositoryFactoryTests.cs b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/EFRepositoryFactoryTests.cs index c30df303..659da398 100644 --- a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/EFRepositoryFactoryTests.cs +++ b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/EFRepositoryFactoryTests.cs @@ -1,91 +1,125 @@ -using System; -using System.Linq; -using System.Threading.Tasks; -using Ardalis.Specification.EntityFrameworkCore.IntegrationTests.Fixture; +using Ardalis.Specification.EntityFrameworkCore.IntegrationTests.Fixture; using Ardalis.Specification.UnitTests.Fixture.Entities; using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Internal; using Microsoft.Extensions.DependencyInjection; +using Moq; using Xunit; -namespace Ardalis.Specification.EntityFrameworkCore.IntegrationTests +namespace Ardalis.Specification.EntityFrameworkCore.IntegrationTests; + +public class EFRepositoryFactoryTests : IClassFixture { - public class EFRepositoryFactoryTests : IClassFixture + protected TestDbContext dbContext; + protected IServiceProvider serviceProvider; + protected IRepositoryFactory> repositoryFactory; + protected IDbContextFactory contextFactory; + + public EFRepositoryFactoryTests(SharedDatabaseFixture fixture) { - protected TestDbContext dbContext; - protected IServiceProvider serviceProvider; - protected IRepositoryFactory> repositoryFactory; - protected IDbContextFactory contextFactory; + dbContext = fixture.CreateContext(); - public EFRepositoryFactoryTests(SharedDatabaseFixture fixture) - { - dbContext = fixture.CreateContext(); - - serviceProvider = new ServiceCollection() - .AddDbContextFactory((builder => builder.UseSqlServer(fixture.Connection)), - ServiceLifetime.Transient).BuildServiceProvider(); - - contextFactory = serviceProvider.GetService>(); - repositoryFactory = - new EFRepositoryFactory, Repository, TestDbContext>(contextFactory); - } - - [Fact] - public async Task Saves_new_entity() - { - var repository = repositoryFactory.CreateRepository(); - var country = await dbContext.Countries.FirstOrDefaultAsync(); + serviceProvider = new ServiceCollection() + .AddDbContextFactory((builder => builder.UseSqlServer(fixture.Connection)), + ServiceLifetime.Transient).BuildServiceProvider(); - var company = new Company(); - company.Name = "Test save new company name"; - company.CountryId = country.Id; + contextFactory = serviceProvider.GetService>(); + repositoryFactory = + new EFRepositoryFactory, Repository, TestDbContext>(contextFactory); + } - await repository.AddAsync(company); - Assert.NotEqual(0, company.Id); - } + [Fact] + public void CorrectlyInstantiatesRepository() + { + var mockContextFactory = new Mock>(); + mockContextFactory.Setup(x => x.CreateDbContext()) + .Returns(() => new SampleDbContext(new DbContextOptions())); - [Fact] - public async Task Updates_existing_entity() - { - var repository = repositoryFactory.CreateRepository(); - var country = await dbContext.Countries.FirstOrDefaultAsync(); + var repositoryFactory = + new EFRepositoryFactory, MyRepository, SampleDbContext>(mockContextFactory + .Object); - var company = new Company { Name = "Test update existing company name", CountryId = country.Id }; - await repository.AddAsync(company); + var repository = repositoryFactory.CreateRepository(); + Assert.IsType>(repository); + } - var existingCompany = await repository.GetByIdAsync(company.Id); - existingCompany.Name = "Updated company name"; - await repository.UpdateAsync(existingCompany); + [Fact] + public async Task Saves_new_entity() + { + var repository = repositoryFactory.CreateRepository(); + var country = await dbContext.Countries.FirstOrDefaultAsync(); - var validationCompany = await dbContext.Companies.FirstOrDefaultAsync(x => x.Id == company.Id); - Assert.Equal(validationCompany.Name, existingCompany.Name); - } + var company = new Company(); + company.Name = "Test save new company name"; + company.CountryId = country.Id; - [Fact] - public async Task Updates_graph() - { - var repository = repositoryFactory.CreateRepository(); - var country = await dbContext.Countries.FirstOrDefaultAsync(); + await repository.AddAsync(company); + Assert.NotEqual(0, company.Id); + } + + [Fact] + public async Task Updates_existing_entity() + { + var repository = repositoryFactory.CreateRepository(); + var country = await dbContext.Countries.FirstOrDefaultAsync(); + + var company = new Company { Name = "Test update existing company name", CountryId = country.Id }; + await repository.AddAsync(company); + + var existingCompany = await repository.GetByIdAsync(company.Id); + existingCompany.Name = "Updated company name"; + await repository.UpdateAsync(existingCompany); - var company = new Company { Name = "Test update graph", CountryId = country.Id }; - var store = new Store { Name = "Store Number 1" }; - company.Stores.Add(store); + var validationCompany = await dbContext.Companies.FirstOrDefaultAsync(x => x.Id == company.Id); + Assert.Equal(validationCompany.Name, existingCompany.Name); + } + + [Fact] + public async Task Updates_graph() + { + var repository = repositoryFactory.CreateRepository(); + var country = await dbContext.Countries.FirstOrDefaultAsync(); + + var company = new Company { Name = "Test update graph", CountryId = country.Id }; + var store = new Store { Name = "Store Number 1" }; + company.Stores.Add(store); + + await repository.AddAsync(company); + + var spec = new GetCompanyWithStoresSpec(company.Id); + var existingCompany = await repository.FirstOrDefaultAsync(spec); + existingCompany.Name = "Updated company name"; + var existingStore = existingCompany.Stores.FirstOrDefault(); + existingStore.Name = "Updated Store Name"; + + await repository.UpdateAsync(existingCompany); + + var validationCompany = await dbContext.Companies.FirstOrDefaultAsync(x => x.Id == company.Id); + Assert.Equal(validationCompany.Name, existingCompany.Name); + + var validationStore = await dbContext.Stores.FirstOrDefaultAsync(x => x.CompanyId == company.Id); + Assert.Equal(validationStore.Name, existingStore.Name); + } - await repository.AddAsync(company); + public record Customer(int Id, string Name); - var spec = new GetCompanyWithStoresSpec(company.Id); - var existingCompany = await repository.FirstOrDefaultAsync(spec); - existingCompany.Name = "Updated company name"; - var existingStore = existingCompany.Stores.FirstOrDefault(); - existingStore.Name = "Updated Store Name"; + public class SampleDbContext : DbContext + { + public DbSet Customers { get; set; } - await repository.UpdateAsync(existingCompany); + public SampleDbContext(DbContextOptions options) + : base(options) + { + } + } - var validationCompany = await dbContext.Companies.FirstOrDefaultAsync(x => x.Id == company.Id); - Assert.Equal(validationCompany.Name, existingCompany.Name); + public interface IRepository : IRepositoryBase where T : class + { + } - var validationStore = await dbContext.Stores.FirstOrDefaultAsync(x => x.CompanyId == company.Id); - Assert.Equal(validationStore.Name, existingStore.Name); + public class MyRepository : RepositoryBase, IRepository where T : class + { + public MyRepository(SampleDbContext dbContext) : base(dbContext) + { } } } diff --git a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/ContextFactoryRepositoryOfT.cs b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/ContextFactoryRepositoryOfT.cs index 80a4fd19..5df09fad 100644 --- a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/ContextFactoryRepositoryOfT.cs +++ b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/ContextFactoryRepositoryOfT.cs @@ -1,17 +1,16 @@ using Microsoft.EntityFrameworkCore; -namespace Ardalis.Specification.EntityFrameworkCore.IntegrationTests.Fixture +namespace Ardalis.Specification.EntityFrameworkCore.IntegrationTests.Fixture; + +public class ContextFactoryRepository : ContextFactoryRepositoryBaseOfT + where T : class where TContext : DbContext { - public class ContextFactoryRepository : ContextFactoryRepositoryBaseOfT - where T : class where TContext : DbContext + public ContextFactoryRepository(IDbContextFactory dbContextFactory) : base(dbContextFactory) { - public ContextFactoryRepository(IDbContextFactory dbContextFactory) : base(dbContextFactory) - { - } + } - public ContextFactoryRepository(IDbContextFactory dbContextFactory, - ISpecificationEvaluator specificationEvaluator) : base(dbContextFactory, specificationEvaluator) - { - } + public ContextFactoryRepository(IDbContextFactory dbContextFactory, + ISpecificationEvaluator specificationEvaluator) : base(dbContextFactory, specificationEvaluator) + { } } diff --git a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/GetCompanyWithStoresSpec.cs b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/GetCompanyWithStoresSpec.cs index e4560e12..02283a81 100644 --- a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/GetCompanyWithStoresSpec.cs +++ b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/GetCompanyWithStoresSpec.cs @@ -1,12 +1,11 @@ using Ardalis.Specification.UnitTests.Fixture.Entities; -namespace Ardalis.Specification.EntityFrameworkCore.IntegrationTests.Fixture +namespace Ardalis.Specification.EntityFrameworkCore.IntegrationTests.Fixture; + +public class GetCompanyWithStoresSpec : Specification, ISingleResultSpecification { - public class GetCompanyWithStoresSpec : Specification, ISingleResultSpecification + public GetCompanyWithStoresSpec(int companyId) { - public GetCompanyWithStoresSpec(int companyId) - { - this.Query.Where(x => x.Id == companyId).Include(x => x.Stores); - } + Query.Where(x => x.Id == companyId).Include(x => x.Stores); } } diff --git a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/IntegrationTestBase.cs b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/IntegrationTestBase.cs index 51fca8c0..5823519a 100644 --- a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/IntegrationTestBase.cs +++ b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/IntegrationTestBase.cs @@ -1,20 +1,19 @@ using Ardalis.Specification.UnitTests.Fixture.Entities; using Xunit; -namespace Ardalis.Specification.EntityFrameworkCore.IntegrationTests.Fixture +namespace Ardalis.Specification.EntityFrameworkCore.IntegrationTests.Fixture; + +public abstract class IntegrationTestBase : IClassFixture { - public abstract class IntegrationTestBase : IClassFixture - { - protected TestDbContext dbContext; - protected Repository companyRepository; - protected Repository storeRepository; + protected TestDbContext dbContext; + protected Repository companyRepository; + protected Repository storeRepository; - protected IntegrationTestBase(SharedDatabaseFixture fixture, ISpecificationEvaluator specificationEvaluator) - { - dbContext = fixture.CreateContext(); + protected IntegrationTestBase(SharedDatabaseFixture fixture, ISpecificationEvaluator specificationEvaluator) + { + dbContext = fixture.CreateContext(); - companyRepository = new Repository(dbContext, specificationEvaluator); - storeRepository = new Repository(dbContext, specificationEvaluator); - } + companyRepository = new Repository(dbContext, specificationEvaluator); + storeRepository = new Repository(dbContext, specificationEvaluator); } } diff --git a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/LoggerFactoryProvider.cs b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/LoggerFactoryProvider.cs index 42a357c8..848a14fe 100644 --- a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/LoggerFactoryProvider.cs +++ b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/LoggerFactoryProvider.cs @@ -1,16 +1,12 @@ -using System; -using System.Collections.Generic; -using System.Text; -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; -namespace Ardalis.Specification.EntityFrameworkCore.IntegrationTests.Fixture +namespace Ardalis.Specification.EntityFrameworkCore.IntegrationTests.Fixture; + +public class LoggerFactoryProvider { - public class LoggerFactoryProvider + public static readonly ILoggerFactory LoggerFactoryInstance = Microsoft.Extensions.Logging.LoggerFactory.Create(builder => { - public static readonly ILoggerFactory LoggerFactoryInstance = Microsoft.Extensions.Logging.LoggerFactory.Create(builder => - { - builder.AddFilter("Ardalis.Specification.EF", LogLevel.Debug); - builder.AddConsole(); - }); - } + builder.AddFilter("Ardalis.Specification.EF", LogLevel.Debug); + builder.AddConsole(); + }); } diff --git a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/RepositoryOfT.cs b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/RepositoryOfT.cs index cc82da8a..74a3ed6d 100644 --- a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/RepositoryOfT.cs +++ b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/RepositoryOfT.cs @@ -1,17 +1,16 @@ -namespace Ardalis.Specification.EntityFrameworkCore.IntegrationTests.Fixture +namespace Ardalis.Specification.EntityFrameworkCore.IntegrationTests.Fixture; + +/// +public class Repository : RepositoryBase where T : class { - /// - public class Repository : RepositoryBase where T : class - { - protected readonly TestDbContext dbContext; + protected readonly TestDbContext dbContext; - public Repository(TestDbContext dbContext) : this(dbContext, SpecificationEvaluator.Default) - { - } + public Repository(TestDbContext dbContext) : this(dbContext, SpecificationEvaluator.Default) + { + } - public Repository(TestDbContext dbContext, ISpecificationEvaluator specificationEvaluator) : base(dbContext, specificationEvaluator) - { - this.dbContext = dbContext; - } + public Repository(TestDbContext dbContext, ISpecificationEvaluator specificationEvaluator) : base(dbContext, specificationEvaluator) + { + this.dbContext = dbContext; } } diff --git a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/SharedDatabaseFixture.cs b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/SharedDatabaseFixture.cs index 92eb4bb6..7fdf88d9 100644 --- a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/SharedDatabaseFixture.cs +++ b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/SharedDatabaseFixture.cs @@ -1,94 +1,87 @@ -using System; -using System.Collections.Generic; -using System.Data.Common; -using System.Text; -using MartinCostello.SqlLocalDb; +using MartinCostello.SqlLocalDb; using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore; +using System.Data.Common; + +namespace Ardalis.Specification.EntityFrameworkCore.IntegrationTests.Fixture; -namespace Ardalis.Specification.EntityFrameworkCore.IntegrationTests.Fixture +public class SharedDatabaseFixture : IDisposable { - public class SharedDatabaseFixture : IDisposable - { - // Docker - public const string ConnectionStringDocker = "Data Source=databaseEFCore;Initial Catalog=SpecificationEFCoreTestsDB;PersistSecurityInfo=True;User ID=sa;Password=P@ssW0rd!"; + public const string _connectionStringDocker = "Data Source=databaseEFCore;Initial Catalog=SpecificationEFCoreTestsDB;PersistSecurityInfo=True;User ID=sa;Password=P@ssW0rd!;TrustServerCertificate=Yes"; + public const string _connectionStringLocalDb = "Server=(localdb)\\mssqllocaldb;Integrated Security=SSPI;Initial Catalog=SpecificationEFTestsDB;ConnectRetryCount=0"; - // (localdb) - public const string ConnectionStringLocalDb = "Server=(localdb)\\mssqllocaldb;Integrated Security=SSPI;Initial Catalog=SpecificationEFTestsDB;ConnectRetryCount=0"; + private static readonly object _lock = new(); + private static bool _databaseInitialized; - private static readonly object _lock = new object(); - private static bool _databaseInitialized; + public SharedDatabaseFixture() + { + var isLocalDBInstalled = false; - public SharedDatabaseFixture() + using (var localDB = new SqlLocalDbApi()) { - var isLocalDBInstalled = false; - - using (var localDB = new SqlLocalDbApi()) - { - isLocalDBInstalled = localDB.IsLocalDBInstalled(); - } + isLocalDBInstalled = localDB.IsLocalDBInstalled(); + } - Connection = isLocalDBInstalled - ? new SqlConnection(ConnectionStringLocalDb) - : new SqlConnection(ConnectionStringDocker); + Connection = isLocalDBInstalled + ? new SqlConnection(_connectionStringLocalDb) + : new SqlConnection(_connectionStringDocker); - Seed(); + Seed(); - Connection.Open(); - } + Connection.Open(); + } - // This would work only if the DB already exists, otherwise obviously won't be able to open a connection. - // Therefore, in the ctor we're using a Nuget package for this check, it's more robust. - private bool IsLocalDbAvailable1() + // This would work only if the DB already exists, otherwise obviously won't be able to open a connection. + // Therefore, in the ctor we're using a Nuget package for this check, it's more robust. + private static bool IsLocalDbAvailable1() + { + try { - try - { - using (var connection = new SqlConnection(ConnectionStringLocalDb)) - { - connection.Open(); - connection.Close(); - } - - return true; - } - catch (Exception) + using (var connection = new SqlConnection(_connectionStringLocalDb)) { - return false; + connection.Open(); + connection.Close(); } - } - - public DbConnection Connection { get; } - public TestDbContext CreateContext(DbTransaction? transaction = null) + return true; + } + catch (Exception) { - var context = new TestDbContext(new DbContextOptionsBuilder().UseSqlServer(Connection).Options); + return false; + } + } - if (transaction != null) - { - context.Database.UseTransaction(transaction); - } + public DbConnection Connection { get; } + + public TestDbContext CreateContext(DbTransaction transaction = null) + { + var context = new TestDbContext(new DbContextOptionsBuilder().UseSqlServer(Connection).Options); - return context; + if (transaction != null) + { + context.Database.UseTransaction(transaction); } - private void Seed() + return context; + } + + private void Seed() + { + lock (_lock) { - lock (_lock) + if (!_databaseInitialized) { - if (!_databaseInitialized) + using (var context = CreateContext()) { - using (var context = CreateContext()) - { - context.Database.EnsureDeleted(); - context.Database.EnsureCreated(); - } - - _databaseInitialized = true; + context.Database.EnsureDeleted(); + context.Database.EnsureCreated(); } + + _databaseInitialized = true; } } - - public void Dispose() => Connection.Dispose(); } + + public void Dispose() => Connection.Dispose(); } diff --git a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/TestDbContext.cs b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/TestDbContext.cs index 80edee5d..8638913f 100644 --- a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/TestDbContext.cs +++ b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/TestDbContext.cs @@ -1,41 +1,37 @@ -using System; -using System.Collections.Generic; -using System.Text; -using Ardalis.Specification.UnitTests.Fixture.Entities; +using Ardalis.Specification.UnitTests.Fixture.Entities; using Ardalis.Specification.UnitTests.Fixture.Entities.Seeds; using Microsoft.EntityFrameworkCore; -namespace Ardalis.Specification.EntityFrameworkCore.IntegrationTests.Fixture +namespace Ardalis.Specification.EntityFrameworkCore.IntegrationTests.Fixture; + +public class TestDbContext : DbContext { - public class TestDbContext : DbContext - { - public DbSet? Countries { get; set; } - public DbSet? Companies { get; set; } - public DbSet? Stores { get; set; } - public DbSet
? Addresses { get; set; } - public DbSet? Products { get; set; } + public DbSet Countries => Set(); + public DbSet Companies => Set(); + public DbSet Stores => Set(); + public DbSet
Addresses => Set
(); + public DbSet Products => Set(); - public TestDbContext(DbContextOptions options) : base(options) - { - } + public TestDbContext(DbContextOptions options) : base(options) + { + } - protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - { - optionsBuilder.UseLoggerFactory(LoggerFactoryProvider.LoggerFactoryInstance); - base.OnConfiguring(optionsBuilder); - } + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + optionsBuilder.UseLoggerFactory(LoggerFactoryProvider.LoggerFactoryInstance); + base.OnConfiguring(optionsBuilder); + } - protected override void OnModelCreating(ModelBuilder modelBuilder) - { - base.OnModelCreating(modelBuilder); + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); - modelBuilder.Entity().HasOne(x => x.Address).WithOne(x => x!.Store!).HasForeignKey
(x => x.StoreId); + modelBuilder.Entity().HasOne(x => x.Address).WithOne(x => x!.Store!).HasForeignKey
(x => x.StoreId); - modelBuilder.Entity().HasData(CountrySeed.Get()); - modelBuilder.Entity().HasData(CompanySeed.Get()); - modelBuilder.Entity
().HasData(AddressSeed.Get()); - modelBuilder.Entity().HasData(StoreSeed.Get()); - modelBuilder.Entity().HasData(ProductSeed.Get()); - } + modelBuilder.Entity().HasData(CountrySeed.Get()); + modelBuilder.Entity().HasData(CompanySeed.Get()); + modelBuilder.Entity
().HasData(AddressSeed.Get()); + modelBuilder.Entity().HasData(StoreSeed.Get()); + modelBuilder.Entity().HasData(ProductSeed.Get()); } } diff --git a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/RepositoryOfT_AnyAsync.cs b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/RepositoryOfT_AnyAsync.cs index 27adfaa2..02225c65 100644 --- a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/RepositoryOfT_AnyAsync.cs +++ b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/RepositoryOfT_AnyAsync.cs @@ -1,52 +1,50 @@ -using System.Threading.Tasks; -using Ardalis.Specification.EntityFrameworkCore.IntegrationTests.Fixture; +using Ardalis.Specification.EntityFrameworkCore.IntegrationTests.Fixture; using Ardalis.Specification.UnitTests.Fixture.Entities.Seeds; using Ardalis.Specification.UnitTests.Fixture.Specs; using FluentAssertions; using Xunit; -namespace Ardalis.Specification.EntityFrameworkCore.IntegrationTests +namespace Ardalis.Specification.EntityFrameworkCore.IntegrationTests; + +public class RepositoryOfT_AnyAsync : RepositoryOfT_AnyAsync_TestKit { - public class RepositoryOfT_AnyAsync : RepositoryOfT_AnyAsync_TestKit + public RepositoryOfT_AnyAsync(SharedDatabaseFixture fixture) : base(fixture, SpecificationEvaluator.Default) { - public RepositoryOfT_AnyAsync(SharedDatabaseFixture fixture) : base(fixture, SpecificationEvaluator.Default) - { - } } +} - public class RepositoryOfT_AnyAsync_Cached : RepositoryOfT_AnyAsync_TestKit +public class RepositoryOfT_AnyAsync_Cached : RepositoryOfT_AnyAsync_TestKit +{ + public RepositoryOfT_AnyAsync_Cached(SharedDatabaseFixture fixture) : base(fixture, SpecificationEvaluator.Cached) { - public RepositoryOfT_AnyAsync_Cached(SharedDatabaseFixture fixture) : base(fixture, SpecificationEvaluator.Cached) - { - } } +} - public abstract class RepositoryOfT_AnyAsync_TestKit : IntegrationTestBase - { - protected RepositoryOfT_AnyAsync_TestKit(SharedDatabaseFixture fixture, ISpecificationEvaluator specificationEvaluator) : base(fixture, specificationEvaluator) { } +public abstract class RepositoryOfT_AnyAsync_TestKit : IntegrationTestBase +{ + protected RepositoryOfT_AnyAsync_TestKit(SharedDatabaseFixture fixture, ISpecificationEvaluator specificationEvaluator) : base(fixture, specificationEvaluator) { } - [Fact] - public virtual async Task ReturnsTrueOnStoresRecords_WithoutSpec() - { - var result = await storeRepository.AnyAsync(); + [Fact] + public virtual async Task ReturnsTrueOnStoresRecords_WithoutSpec() + { + var result = await storeRepository.AnyAsync(); - result.Should().BeTrue(); - } + result.Should().BeTrue(); + } - [Fact] - public virtual async Task ReturnsTrue_GivenStoreByIdSpecWithValidStore() - { - var result = await storeRepository.AnyAsync(new StoreByIdSpec(StoreSeed.VALID_STORE_ID)); + [Fact] + public virtual async Task ReturnsTrue_GivenStoreByIdSpecWithValidStore() + { + var result = await storeRepository.AnyAsync(new StoreByIdSpec(StoreSeed.VALID_STORE_ID)); - result.Should().BeTrue(); - } + result.Should().BeTrue(); + } - [Fact] - public virtual async Task ReturnsFalse_GivenStoreByIdSpecWithInvalidStore() - { - var result = await storeRepository.AnyAsync(new StoreByIdSpec(0)); + [Fact] + public virtual async Task ReturnsFalse_GivenStoreByIdSpecWithInvalidStore() + { + var result = await storeRepository.AnyAsync(new StoreByIdSpec(0)); - result.Should().BeFalse(); - } + result.Should().BeFalse(); } } diff --git a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/RepositoryOfT_AsAsyncEnumerable.cs b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/RepositoryOfT_AsAsyncEnumerable.cs index 9825bea7..0bca7580 100644 --- a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/RepositoryOfT_AsAsyncEnumerable.cs +++ b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/RepositoryOfT_AsAsyncEnumerable.cs @@ -1,56 +1,52 @@ -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Ardalis.Specification.EntityFrameworkCore.IntegrationTests.Fixture; +using Ardalis.Specification.EntityFrameworkCore.IntegrationTests.Fixture; using Ardalis.Specification.UnitTests.Fixture.Specs; using FluentAssertions; using Xunit; -namespace Ardalis.Specification.EntityFrameworkCore.IntegrationTests +namespace Ardalis.Specification.EntityFrameworkCore.IntegrationTests; + +public class RepositoryOfT_AsAsyncEnumerable : RepositoryOfT_AnyAsync_TestKit { - public class RepositoryOfT_AsAsyncEnumerable : RepositoryOfT_AnyAsync_TestKit + public RepositoryOfT_AsAsyncEnumerable(SharedDatabaseFixture fixture) + : base(fixture, SpecificationEvaluator.Default) + { + } +} + +public abstract class RepositoryOfT_AsAsyncEnumerable_TestKit : IntegrationTestBase +{ + protected RepositoryOfT_AsAsyncEnumerable_TestKit(SharedDatabaseFixture fixture, ISpecificationEvaluator specificationEvaluator) + : base(fixture, specificationEvaluator) { - public RepositoryOfT_AsAsyncEnumerable(SharedDatabaseFixture fixture) - : base(fixture, SpecificationEvaluator.Default) - { - } } - public abstract class RepositoryOfT_AsAsyncEnumerable_TestKit : IntegrationTestBase + [Fact] + public virtual async Task ReturnsTrueOnStoresRecords_WithoutSpec() { - protected RepositoryOfT_AsAsyncEnumerable_TestKit(SharedDatabaseFixture fixture, ISpecificationEvaluator specificationEvaluator) - : base(fixture, specificationEvaluator) + var results = storeRepository.AsAsyncEnumerable(new StoreIncludeProductsSpec()); + + await foreach (var result in results.WithCancellation(CancellationToken.None)) { + result.Should().NotBeNull(); + result.Products.Should().NotBeEmpty(); } - - [Fact] - public virtual async Task ReturnsTrueOnStoresRecords_WithoutSpec() - { - var results = storeRepository.AsAsyncEnumerable(new StoreIncludeProductsSpec()); + } - await foreach (var result in results.WithCancellation(CancellationToken.None)) - { - result.Should().NotBeNull(); - result.Products.Should().NotBeEmpty(); - } - } - - [Fact] - public virtual async Task ReturnsStoreWithIdFrom15To30_GivenStoresByIdAsAsyncEnumerableSpec() + [Fact] + public virtual async Task ReturnsStoreWithIdFrom15To30_GivenStoresByIdAsAsyncEnumerableSpec() + { + var ids = Enumerable.Range(15, 16); + var spec = new StoresByIdListSpec(ids); + + var counter = 0; + var results = storeRepository.AsAsyncEnumerable(spec); + await foreach (var result in results.WithCancellation(CancellationToken.None)) { - var ids = Enumerable.Range(15, 16); - var spec = new StoresByIdListSpec(ids); - - int counter = 0; - var results = storeRepository.AsAsyncEnumerable(spec); - await foreach (var result in results.WithCancellation(CancellationToken.None)) - { - result.Should().NotBeNull(); - result.Products.Should().NotBeEmpty(); - ++counter; - } - - counter.Should().Be(16); + result.Should().NotBeNull(); + result.Products.Should().NotBeEmpty(); + ++counter; } + + counter.Should().Be(16); } } diff --git a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/RepositoryOfT_GetById.cs b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/RepositoryOfT_GetById.cs index 95b6bba0..65f991e6 100644 --- a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/RepositoryOfT_GetById.cs +++ b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/RepositoryOfT_GetById.cs @@ -1,45 +1,43 @@ -using System.Threading.Tasks; -using Ardalis.Specification.EntityFrameworkCore.IntegrationTests.Fixture; +using Ardalis.Specification.EntityFrameworkCore.IntegrationTests.Fixture; using Ardalis.Specification.UnitTests.Fixture.Entities.Seeds; using FluentAssertions; using Xunit; -namespace Ardalis.Specification.EntityFrameworkCore.IntegrationTests +namespace Ardalis.Specification.EntityFrameworkCore.IntegrationTests; + +public class RepositoryOfT_GetById : RepositoryOfT_GetById_TestKit { - public class RepositoryOfT_GetById : RepositoryOfT_GetById_TestKit + public RepositoryOfT_GetById(SharedDatabaseFixture fixture) : base(fixture, SpecificationEvaluator.Default) { - public RepositoryOfT_GetById(SharedDatabaseFixture fixture) : base(fixture, SpecificationEvaluator.Default) - { - } } +} - public class RepositoryOfT_GetById_Cached : RepositoryOfT_GetById_TestKit +public class RepositoryOfT_GetById_Cached : RepositoryOfT_GetById_TestKit +{ + public RepositoryOfT_GetById_Cached(SharedDatabaseFixture fixture) : base(fixture, SpecificationEvaluator.Cached) { - public RepositoryOfT_GetById_Cached(SharedDatabaseFixture fixture) : base(fixture, SpecificationEvaluator.Cached) - { - } } +} - public abstract class RepositoryOfT_GetById_TestKit : IntegrationTestBase - { - protected RepositoryOfT_GetById_TestKit(SharedDatabaseFixture fixture, ISpecificationEvaluator specificationEvaluator) : base(fixture, specificationEvaluator) { } +public abstract class RepositoryOfT_GetById_TestKit : IntegrationTestBase +{ + protected RepositoryOfT_GetById_TestKit(SharedDatabaseFixture fixture, ISpecificationEvaluator specificationEvaluator) : base(fixture, specificationEvaluator) { } - [Fact] - public virtual async Task ReturnsStore_GivenId() - { - var result = await storeRepository.GetByIdAsync(StoreSeed.VALID_STORE_ID); + [Fact] + public virtual async Task ReturnsStore_GivenId() + { + var result = await storeRepository.GetByIdAsync(StoreSeed.VALID_STORE_ID); - result.Should().NotBeNull(); - result!.Name.Should().Be(StoreSeed.VALID_STORE_NAME); - } + result.Should().NotBeNull(); + result!.Name.Should().Be(StoreSeed.VALID_STORE_NAME); + } - [Fact] - public virtual async Task ReturnsStore_GivenGenericId() - { - var result = await storeRepository.GetByIdAsync(StoreSeed.VALID_STORE_ID); + [Fact] + public virtual async Task ReturnsStore_GivenGenericId() + { + var result = await storeRepository.GetByIdAsync(StoreSeed.VALID_STORE_ID); - result.Should().NotBeNull(); - result!.Name.Should().Be(StoreSeed.VALID_STORE_NAME); - } + result.Should().NotBeNull(); + result!.Name.Should().Be(StoreSeed.VALID_STORE_NAME); } } diff --git a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/RepositoryOfT_GetBySpec.cs b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/RepositoryOfT_GetBySpec.cs index 7804728b..03c89e24 100644 --- a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/RepositoryOfT_GetBySpec.cs +++ b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/RepositoryOfT_GetBySpec.cs @@ -1,117 +1,114 @@ -using System.Linq; -using System.Threading.Tasks; -using Ardalis.Specification.EntityFrameworkCore.IntegrationTests.Fixture; +using Ardalis.Specification.EntityFrameworkCore.IntegrationTests.Fixture; using Ardalis.Specification.UnitTests.Fixture.Entities.Seeds; using Ardalis.Specification.UnitTests.Fixture.Specs; using FluentAssertions; using Xunit; -namespace Ardalis.Specification.EntityFrameworkCore.IntegrationTests +namespace Ardalis.Specification.EntityFrameworkCore.IntegrationTests; + +public class RepositoryOfT_GetBySpec : RepositoryOfT_GetBySpec_TestKit +{ + public RepositoryOfT_GetBySpec(SharedDatabaseFixture fixture) : base(fixture, SpecificationEvaluator.Default) + { + } +} + +public class RepositoryOfT_GetBySpec_Cached : RepositoryOfT_GetBySpec_TestKit +{ + public RepositoryOfT_GetBySpec_Cached(SharedDatabaseFixture fixture) : base(fixture, SpecificationEvaluator.Cached) + { + } +} + +public abstract class RepositoryOfT_GetBySpec_TestKit : IntegrationTestBase { - public class RepositoryOfT_GetBySpec : RepositoryOfT_GetBySpec_TestKit + protected RepositoryOfT_GetBySpec_TestKit(SharedDatabaseFixture fixture, ISpecificationEvaluator specificationEvaluator) : base(fixture, specificationEvaluator) { } + + [Fact] + public virtual async Task ReturnsStoreWithProducts_GivenStoreByIdIncludeProductsSpec() { - public RepositoryOfT_GetBySpec(SharedDatabaseFixture fixture) : base(fixture, SpecificationEvaluator.Default) - { - } + var result = await storeRepository.GetBySpecAsync(new StoreByIdIncludeProductsSpec(StoreSeed.VALID_STORE_ID)); + + result.Should().NotBeNull(); + result!.Name.Should().Be(StoreSeed.VALID_STORE_NAME); + result.Products.Count.Should().BeGreaterThan(1); } - public class RepositoryOfT_GetBySpec_Cached : RepositoryOfT_GetBySpec_TestKit + [Fact] + public virtual async Task ReturnsStoreWithAddress_GivenStoreByIdIncludeAddressSpec() { - public RepositoryOfT_GetBySpec_Cached(SharedDatabaseFixture fixture) : base(fixture, SpecificationEvaluator.Cached) - { - } + var result = await storeRepository.GetBySpecAsync(new StoreByIdIncludeAddressSpec(StoreSeed.VALID_STORE_ID)); + + result.Should().NotBeNull(); + result!.Name.Should().Be(StoreSeed.VALID_STORE_NAME); + result.Address?.Street.Should().Be(AddressSeed.VALID_STREET_FOR_STOREID1); + } + + [Fact] + public virtual async Task ReturnsStoreWithAddressAndProduct_GivenStoreByIdIncludeAddressAndProductsSpec() + { + var result = await storeRepository.GetBySpecAsync(new StoreByIdIncludeAddressAndProductsSpec(StoreSeed.VALID_STORE_ID)); + + result.Should().NotBeNull(); + result!.Name.Should().Be(StoreSeed.VALID_STORE_NAME); + result.Products.Count.Should().BeGreaterThan(1); + result.Address?.Street.Should().Be(AddressSeed.VALID_STREET_FOR_STOREID1); + } + + [Fact] + public virtual async Task ReturnsStoreWithProducts_GivenStoreByIdIncludeProductsUsingStringSpec() + { + var result = await storeRepository.GetBySpecAsync(new StoreByIdIncludeProductsUsingStringSpec(StoreSeed.VALID_STORE_ID)); + + result.Should().NotBeNull(); + result!.Name.Should().Be(StoreSeed.VALID_STORE_NAME); + result.Products.Count.Should().BeGreaterThan(1); + } + + [Fact] + public virtual async Task ReturnsCompanyWithStoresAndAddress_GivenCompanyByIdIncludeStoresThenIncludeAddressSpec() + { + var result = await companyRepository.GetBySpecAsync(new CompanyByIdIncludeStoresThenIncludeAddressSpec(CompanySeed.VALID_COMPANY_ID)); + + result.Should().NotBeNull(); + result!.Name.Should().Be(CompanySeed.VALID_COMPANY_NAME); + result.Stores.Count.Should().BeGreaterThan(49); + result.Stores.Select(x => x.Address).Count().Should().BeGreaterThan(0); + } + + [Fact] + public virtual async Task ReturnsCompanyWithStoresAndProducts_GivenCompanyByIdIncludeStoresThenIncludeProductsSpec() + { + var result = await companyRepository.GetBySpecAsync(new CompanyByIdIncludeStoresThenIncludeProductsSpec(CompanySeed.VALID_COMPANY_ID)); + + result.Should().NotBeNull(); + result!.Name.Should().Be(CompanySeed.VALID_COMPANY_NAME); + result.Stores.Count.Should().BeGreaterThan(49); + result.Stores.Select(x => x.Products).Count().Should().BeGreaterThan(1); + } + + [Fact] + public virtual async Task ReturnsUntrackedCompany_GivenCompanyByIdAsUntrackedSpec() + { + dbContext.ChangeTracker.Clear(); + + var result = await companyRepository.GetBySpecAsync(new CompanyByIdAsUntrackedSpec(CompanySeed.VALID_COMPANY_ID)); + + result.Should().NotBeNull(); + result?.Name.Should().Be(CompanySeed.VALID_COMPANY_NAME); + dbContext.Entry(result!).State.Should().Be(Microsoft.EntityFrameworkCore.EntityState.Detached); } - public abstract class RepositoryOfT_GetBySpec_TestKit : IntegrationTestBase + [Fact] + public virtual async Task ReturnsStoreWithCompanyAndCountryAndStoresForCompany_GivenStoreByIdIncludeCompanyAndCountryAndStoresForCompanySpec() { - protected RepositoryOfT_GetBySpec_TestKit(SharedDatabaseFixture fixture, ISpecificationEvaluator specificationEvaluator) : base(fixture, specificationEvaluator) { } - - [Fact] - public virtual async Task ReturnsStoreWithProducts_GivenStoreByIdIncludeProductsSpec() - { - var result = await storeRepository.GetBySpecAsync(new StoreByIdIncludeProductsSpec(StoreSeed.VALID_STORE_ID)); - - result.Should().NotBeNull(); - result!.Name.Should().Be(StoreSeed.VALID_STORE_NAME); - result.Products.Count.Should().BeGreaterThan(1); - } - - [Fact] - public virtual async Task ReturnsStoreWithAddress_GivenStoreByIdIncludeAddressSpec() - { - var result = await storeRepository.GetBySpecAsync(new StoreByIdIncludeAddressSpec(StoreSeed.VALID_STORE_ID)); - - result.Should().NotBeNull(); - result!.Name.Should().Be(StoreSeed.VALID_STORE_NAME); - result.Address?.Street.Should().Be(AddressSeed.VALID_STREET_FOR_STOREID1); - } - - [Fact] - public virtual async Task ReturnsStoreWithAddressAndProduct_GivenStoreByIdIncludeAddressAndProductsSpec() - { - var result = await storeRepository.GetBySpecAsync(new StoreByIdIncludeAddressAndProductsSpec(StoreSeed.VALID_STORE_ID)); - - result.Should().NotBeNull(); - result!.Name.Should().Be(StoreSeed.VALID_STORE_NAME); - result.Products.Count.Should().BeGreaterThan(1); - result.Address?.Street.Should().Be(AddressSeed.VALID_STREET_FOR_STOREID1); - } - - [Fact] - public virtual async Task ReturnsStoreWithProducts_GivenStoreByIdIncludeProductsUsingStringSpec() - { - var result = await storeRepository.GetBySpecAsync(new StoreByIdIncludeProductsUsingStringSpec(StoreSeed.VALID_STORE_ID)); - - result.Should().NotBeNull(); - result!.Name.Should().Be(StoreSeed.VALID_STORE_NAME); - result.Products.Count.Should().BeGreaterThan(1); - } - - [Fact] - public virtual async Task ReturnsCompanyWithStoresAndAddress_GivenCompanyByIdIncludeStoresThenIncludeAddressSpec() - { - var result = await companyRepository.GetBySpecAsync(new CompanyByIdIncludeStoresThenIncludeAddressSpec(CompanySeed.VALID_COMPANY_ID)); - - result.Should().NotBeNull(); - result!.Name.Should().Be(CompanySeed.VALID_COMPANY_NAME); - result.Stores.Count.Should().BeGreaterThan(49); - result.Stores.Select(x => x.Address).Count().Should().BeGreaterThan(0); - } - - [Fact] - public virtual async Task ReturnsCompanyWithStoresAndProducts_GivenCompanyByIdIncludeStoresThenIncludeProductsSpec() - { - var result = await companyRepository.GetBySpecAsync(new CompanyByIdIncludeStoresThenIncludeProductsSpec(CompanySeed.VALID_COMPANY_ID)); - - result.Should().NotBeNull(); - result!.Name.Should().Be(CompanySeed.VALID_COMPANY_NAME); - result.Stores.Count.Should().BeGreaterThan(49); - result.Stores.Select(x => x.Products).Count().Should().BeGreaterThan(1); - } - - [Fact] - public virtual async Task ReturnsUntrackedCompany_GivenCompanyByIdAsUntrackedSpec() - { - dbContext.ChangeTracker.Clear(); - - var result = await companyRepository.GetBySpecAsync(new CompanyByIdAsUntrackedSpec(CompanySeed.VALID_COMPANY_ID)); - - result.Should().NotBeNull(); - result?.Name.Should().Be(CompanySeed.VALID_COMPANY_NAME); - dbContext.Entry(result!).State.Should().Be(Microsoft.EntityFrameworkCore.EntityState.Detached); - } - - [Fact] - public virtual async Task ReturnsStoreWithCompanyAndCountryAndStoresForCompany_GivenStoreByIdIncludeCompanyAndCountryAndStoresForCompanySpec() - { - var result = await storeRepository.GetBySpecAsync(new StoreByIdIncludeCompanyAndCountryAndStoresForCompanySpec(StoreSeed.VALID_STORE_ID)); - - result.Should().NotBeNull(); - result!.Name.Should().Be(StoreSeed.VALID_STORE_NAME); - result.Company.Should().NotBeNull(); - result.Company!.Country.Should().NotBeNull(); - result.Company!.Stores.Should().HaveCountGreaterOrEqualTo(2); - result.Company?.Stores?.Should().Match(x => x.Any(z => z.Products.Count > 0)); - } + var result = await storeRepository.GetBySpecAsync(new StoreByIdIncludeCompanyAndCountryAndStoresForCompanySpec(StoreSeed.VALID_STORE_ID)); + + result.Should().NotBeNull(); + result!.Name.Should().Be(StoreSeed.VALID_STORE_NAME); + result.Company.Should().NotBeNull(); + result.Company!.Country.Should().NotBeNull(); + result.Company!.Stores.Should().HaveCountGreaterOrEqualTo(2); + result.Company?.Stores?.Should().Match(x => x.Any(z => z.Products.Count > 0)); } } diff --git a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/RepositoryOfT_ListAsync.cs b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/RepositoryOfT_ListAsync.cs index ee00cc82..f4cde4f4 100644 --- a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/RepositoryOfT_ListAsync.cs +++ b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/RepositoryOfT_ListAsync.cs @@ -1,210 +1,207 @@ -using System.Linq; -using System.Threading.Tasks; -using Ardalis.Specification.EntityFrameworkCore.IntegrationTests.Fixture; +using Ardalis.Specification.EntityFrameworkCore.IntegrationTests.Fixture; using Ardalis.Specification.UnitTests.Fixture.Entities.Seeds; using Ardalis.Specification.UnitTests.Fixture.Specs; using FluentAssertions; using Xunit; -namespace Ardalis.Specification.EntityFrameworkCore.IntegrationTests +namespace Ardalis.Specification.EntityFrameworkCore.IntegrationTests; + +public class RepositoryOfT_ListAsync : RepositoryOfT_ListAsync_TestKit +{ + public RepositoryOfT_ListAsync(SharedDatabaseFixture fixture) : base(fixture, SpecificationEvaluator.Default) + { + } +} + +public class RepositoryOfT_ListAsync_Cached : RepositoryOfT_ListAsync_TestKit +{ + public RepositoryOfT_ListAsync_Cached(SharedDatabaseFixture fixture) : base(fixture, SpecificationEvaluator.Cached) + { + } +} + +public abstract class RepositoryOfT_ListAsync_TestKit : IntegrationTestBase { - public class RepositoryOfT_ListAsync : RepositoryOfT_ListAsync_TestKit + protected RepositoryOfT_ListAsync_TestKit(SharedDatabaseFixture fixture, ISpecificationEvaluator specificationEvaluator) : base(fixture, specificationEvaluator) { } + + [Fact] + public virtual async Task ReturnsStoreWithProducts_GivenStoreIncludeProductsSpec() + { + var result = await storeRepository.ListAsync(new StoreIncludeProductsSpec()); + + result.Should().NotBeNull(); + result.Should().NotBeEmpty(); + result[0].Products.Should().NotBeEmpty(); + } + + [Fact] + public virtual async Task ReturnsStoreWithAddress_GivenStoreIncludeAddressSpec() { - public RepositoryOfT_ListAsync(SharedDatabaseFixture fixture) : base(fixture, SpecificationEvaluator.Default) - { - } + var result = await storeRepository.ListAsync(new StoreIncludeAddressSpec()); + + result.Should().NotBeNull(); + result.Should().NotBeEmpty(); + result[0].Address.Should().NotBeNull(); } - public class RepositoryOfT_ListAsync_Cached : RepositoryOfT_ListAsync_TestKit + [Fact] + public virtual async Task ReturnsStoreWithAddressAndProduct_GivenStoreIncludeAddressAndProductsSpec() { - public RepositoryOfT_ListAsync_Cached(SharedDatabaseFixture fixture) : base(fixture, SpecificationEvaluator.Cached) - { - } + var result = await storeRepository.ListAsync(new StoreIncludeAddressAndProductsSpec()); + + result.Should().NotBeNull(); + result.Should().NotBeEmpty(); + result[0].Address.Should().NotBeNull(); + result[0].Products.Should().NotBeEmpty(); + } + + [Fact] + public virtual async Task ReturnsCompanyWithStoreWithIdOne_GivenCompanyIncludeFilteredStoresSpec() + { + var result = await companyRepository.ListAsync(new CompanyIncludeFilteredStoresSpec(1)); + + result.Should().NotBeNull(); + result.Should().NotBeEmpty(); + result[0].Stores.Should().NotBeEmpty(); + result[0].Stores.Should().HaveCount(1); + result[0].Stores.First().Id.Should().Be(1); } - public abstract class RepositoryOfT_ListAsync_TestKit : IntegrationTestBase + [Fact] + public virtual async Task ReturnsStoreWithIdFrom15To30_GivenStoresByIdListSpec() { - protected RepositoryOfT_ListAsync_TestKit(SharedDatabaseFixture fixture, ISpecificationEvaluator specificationEvaluator) : base(fixture, specificationEvaluator) { } + var ids = Enumerable.Range(15, 16); + var spec = new StoresByIdListSpec(ids); - [Fact] - public virtual async Task ReturnsStoreWithProducts_GivenStoreIncludeProductsSpec() - { - var result = await storeRepository.ListAsync(new StoreIncludeProductsSpec()); + var stores = await storeRepository.ListAsync(spec); - result.Should().NotBeNull(); - result.Should().NotBeEmpty(); - result[0].Products.Should().NotBeEmpty(); - } + stores.Count.Should().Be(16); + stores.OrderBy(x => x.Id).First().Id.Should().Be(15); + stores.OrderBy(x => x.Id).Last().Id.Should().Be(30); + } - [Fact] - public virtual async Task ReturnsStoreWithAddress_GivenStoreIncludeAddressSpec() - { - var result = await storeRepository.ListAsync(new StoreIncludeAddressSpec()); + [Fact] + public virtual async Task ReturnsSecondPageOfStoreNames_GivenStoreNamesPaginatedSpec() + { + var take = 10; // pagesize 10 + var skip = (2 - 1) * 10; // page 2 - result.Should().NotBeNull(); - result.Should().NotBeEmpty(); - result[0].Address.Should().NotBeNull(); - } + var spec = new StoreNamesPaginatedSpec(skip, take); - [Fact] - public virtual async Task ReturnsStoreWithAddressAndProduct_GivenStoreIncludeAddressAndProductsSpec() - { - var result = await storeRepository.ListAsync(new StoreIncludeAddressAndProductsSpec()); + var storeNames = await storeRepository.ListAsync(spec); - result.Should().NotBeNull(); - result.Should().NotBeEmpty(); - result[0].Address.Should().NotBeNull(); - result[0].Products.Should().NotBeEmpty(); - } + storeNames.Count.Should().Be(take); + storeNames.First().Should().Be("Store 11"); + storeNames.Last().Should().Be("Store 20"); + } - [Fact] - public virtual async Task ReturnsCompanyWithStoreWithIdOne_GivenCompanyIncludeFilteredStoresSpec() - { - var result = await companyRepository.ListAsync(new CompanyIncludeFilteredStoresSpec(1)); + [Fact] + public virtual async Task ReturnsSecondPageOfStores_GivenStoresPaginatedSpec() + { + var take = 10; // pagesize 10 + var skip = (2 - 1) * 10; // page 2 - result.Should().NotBeNull(); - result.Should().NotBeEmpty(); - result[0].Stores.Should().NotBeEmpty(); - result[0].Stores.Should().HaveCount(1); - result[0].Stores.First().Id.Should().Be(1); - } + var spec = new StoresPaginatedSpec(skip, take); - [Fact] - public virtual async Task ReturnsStoreWithIdFrom15To30_GivenStoresByIdListSpec() - { - var ids = Enumerable.Range(15, 16); - var spec = new StoresByIdListSpec(ids); + var stores = await storeRepository.ListAsync(spec); - var stores = await storeRepository.ListAsync(spec); + stores.Count.Should().Be(take); + stores.OrderBy(x => x.Id).First().Id.Should().Be(11); + stores.OrderBy(x => x.Id).Last().Id.Should().Be(20); + } - stores.Count.Should().Be(16); - stores.OrderBy(x => x.Id).First().Id.Should().Be(15); - stores.OrderBy(x => x.Id).Last().Id.Should().Be(30); - } + [Fact] + public virtual async Task ReturnsOrderStoresByNameDescForCompanyWithId2_GivenStoresByCompanyOrderedDescByNameSpec() + { + var spec = new StoresByCompanyOrderedDescByNameSpec(2); - [Fact] - public virtual async Task ReturnsSecondPageOfStoreNames_GivenStoreNamesPaginatedSpec() - { - int take = 10; // pagesize 10 - int skip = (2 - 1) * 10; // page 2 + var stores = await storeRepository.ListAsync(spec); - var spec = new StoreNamesPaginatedSpec(skip, take); + stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_FIRST_ID); + stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_LAST_ID); + } + + [Fact] + public virtual async Task ReturnsOrderStoresByNameDescThenByIdForCompanyWithId2_GivenStoresByCompanyOrderedDescByNameThenByIdSpec() + { + var spec = new StoresByCompanyOrderedDescByNameThenByIdSpec(2); - var storeNames = await storeRepository.ListAsync(spec); + var stores = await storeRepository.ListAsync(spec); + + stores.First().Id.Should().Be(99); + stores.Last().Id.Should().Be(98); + } - storeNames.Count.Should().Be(take); - storeNames.First().Should().Be("Store 11"); - storeNames.Last().Should().Be("Store 20"); - } + [Fact] + public virtual async Task ReturnsSecondPageOfStoresForCompanyWithId2_GivenStoresByCompanyPaginatedOrderedDescByNameSpec() + { + var take = 10; // pagesize 10 + var skip = (2 - 1) * 10; // page 2 - [Fact] - public virtual async Task ReturnsSecondPageOfStores_GivenStoresPaginatedSpec() - { - int take = 10; // pagesize 10 - int skip = (2 - 1) * 10; // page 2 + var spec = new StoresByCompanyPaginatedOrderedDescByNameSpec(2, skip, take); - var spec = new StoresPaginatedSpec(skip, take); + var stores = await storeRepository.ListAsync(spec); - var stores = await storeRepository.ListAsync(spec); + stores.Count.Should().Be(take); + stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_PAGE2_FIRST_ID); + stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_PAGE2_LAST_ID); + } - stores.Count.Should().Be(take); - stores.OrderBy(x => x.Id).First().Id.Should().Be(11); - stores.OrderBy(x => x.Id).Last().Id.Should().Be(20); - } + [Fact] + public virtual async Task ReturnsSecondPageOfStoresForCompanyWithId2_GivenStoresByCompanyPaginatedSpec() + { + var take = 10; // pagesize 10 + var skip = (2 - 1) * 10; // page 2 - [Fact] - public virtual async Task ReturnsOrderStoresByNameDescForCompanyWithId2_GivenStoresByCompanyOrderedDescByNameSpec() - { - var spec = new StoresByCompanyOrderedDescByNameSpec(2); + var spec = new StoresByCompanyPaginatedSpec(2, skip, take); - var stores = await storeRepository.ListAsync(spec); - - stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_FIRST_ID); - stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_LAST_ID); - } - - [Fact] - public virtual async Task ReturnsOrderStoresByNameDescThenByIdForCompanyWithId2_GivenStoresByCompanyOrderedDescByNameThenByIdSpec() - { - var spec = new StoresByCompanyOrderedDescByNameThenByIdSpec(2); - - var stores = await storeRepository.ListAsync(spec); - - stores.First().Id.Should().Be(99); - stores.Last().Id.Should().Be(98); - } - - [Fact] - public virtual async Task ReturnsSecondPageOfStoresForCompanyWithId2_GivenStoresByCompanyPaginatedOrderedDescByNameSpec() - { - int take = 10; // pagesize 10 - int skip = (2 - 1) * 10; // page 2 - - var spec = new StoresByCompanyPaginatedOrderedDescByNameSpec(2, skip, take); - - var stores = await storeRepository.ListAsync(spec); - - stores.Count.Should().Be(take); - stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_PAGE2_FIRST_ID); - stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_PAGE2_LAST_ID); - } - - [Fact] - public virtual async Task ReturnsSecondPageOfStoresForCompanyWithId2_GivenStoresByCompanyPaginatedSpec() - { - int take = 10; // pagesize 10 - int skip = (2 - 1) * 10; // page 2 - - var spec = new StoresByCompanyPaginatedSpec(2, skip, take); + var stores = await storeRepository.ListAsync(spec); - var stores = await storeRepository.ListAsync(spec); - - stores.Count.Should().Be(take); - stores.OrderBy(x => x.Id).First().Id.Should().Be(61); - stores.OrderBy(x => x.Id).Last().Id.Should().Be(70); - } + stores.Count.Should().Be(take); + stores.OrderBy(x => x.Id).First().Id.Should().Be(61); + stores.OrderBy(x => x.Id).Last().Id.Should().Be(70); + } - [Fact] - public virtual async Task ReturnsOrderedStores_GivenStoresOrderedSpecByName() - { - var spec = new StoresOrderedSpecByName(); + [Fact] + public virtual async Task ReturnsOrderedStores_GivenStoresOrderedSpecByName() + { + var spec = new StoresOrderedSpecByName(); - var stores = await storeRepository.ListAsync(spec); + var stores = await storeRepository.ListAsync(spec); - stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_FIRST_ID); - stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_LAST_ID); - } + stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_FIRST_ID); + stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_LAST_ID); + } - [Fact] - public virtual async Task ReturnsOrderedStores_GivenStoresOrderedDescendingByNameSpec() - { - var spec = new StoresOrderedDescendingByNameSpec(); + [Fact] + public virtual async Task ReturnsOrderedStores_GivenStoresOrderedDescendingByNameSpec() + { + var spec = new StoresOrderedDescendingByNameSpec(); - var stores = await storeRepository.ListAsync(spec); + var stores = await storeRepository.ListAsync(spec); - stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FIRST_ID); - stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_LAST_ID); - } + stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FIRST_ID); + stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_LAST_ID); + } - [Fact] - public virtual async Task ReturnsStoreContainingCity1_GivenStoreIncludeProductsSpec() - { - var result = await storeRepository.ListAsync(new StoreSearchByNameOrCitySpec(StoreSeed.VALID_Search_City_Key)); + [Fact] + public virtual async Task ReturnsStoreContainingCity1_GivenStoreIncludeProductsSpec() + { + var result = await storeRepository.ListAsync(new StoreSearchByNameOrCitySpec(StoreSeed.VALID_Search_City_Key)); - result.Should().NotBeNull(); - result.Should().ContainSingle(); - result[0].Id.Should().Be(StoreSeed.VALID_Search_ID); - result[0].City.Should().Contain(StoreSeed.VALID_Search_City_Key); - } + result.Should().NotBeNull(); + result.Should().ContainSingle(); + result[0].Id.Should().Be(StoreSeed.VALID_Search_ID); + result[0].City.Should().Contain(StoreSeed.VALID_Search_City_Key); + } - [Fact] - public virtual async Task ReturnsAllProducts_GivenStoreSelectManyProductsSpec() - { - var result = await storeRepository.ListAsync(new StoreProductNamesSpec()); + [Fact] + public virtual async Task ReturnsAllProducts_GivenStoreSelectManyProductsSpec() + { + var result = await storeRepository.ListAsync(new StoreProductNamesSpec()); - result.Should().NotBeNull(); - result.Should().HaveCount(ProductSeed.TOTAL_PRODUCT_COUNT); - result.OrderBy(x => x).First().Should().Be(ProductSeed.VALID_PRODUCT_NAME); - } + result.Should().NotBeNull(); + result.Should().HaveCount(ProductSeed.TOTAL_PRODUCT_COUNT); + result.OrderBy(x => x).First().Should().Be(ProductSeed.VALID_PRODUCT_NAME); } } diff --git a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.UnitTests/Ardalis.Specification.EntityFrameworkCore.UnitTests.csproj b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.UnitTests/Ardalis.Specification.EntityFrameworkCore.UnitTests.csproj deleted file mode 100644 index 059f6c6c..00000000 --- a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.UnitTests/Ardalis.Specification.EntityFrameworkCore.UnitTests.csproj +++ /dev/null @@ -1,30 +0,0 @@ - - - - net6.0 - enable - enable - - false - - - - - - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - - - - - - - diff --git a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.UnitTests/EFRepositoryFactoryTests.cs b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.UnitTests/EFRepositoryFactoryTests.cs deleted file mode 100644 index 07d50d64..00000000 --- a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.UnitTests/EFRepositoryFactoryTests.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Ardalis.SampleApp.Core.Entities.CustomerAggregate; -using Ardalis.SampleApp.Core.Interfaces; -using Ardalis.SampleApp.Infrastructure.Data; -using Ardalis.SampleApp.Infrastructure.DataAccess; -using Microsoft.EntityFrameworkCore; -using Moq; -using Xunit; - -namespace Ardalis.Specification.EntityFrameworkCore.UnitTests; - -public class EFRepositoryFactoryTests -{ - [Fact] - public void CorrectlyInstantiatesRepository() - { - var mockContextFactory = new Mock>(); - mockContextFactory.Setup(x => x.CreateDbContext()) - .Returns(() => new SampleDbContext(new DbContextOptions())); - - var repositoryFactory = - new EFRepositoryFactory, MyRepository, SampleDbContext>(mockContextFactory - .Object); - - var repository = repositoryFactory.CreateRepository(); - Assert.IsType>(repository); - } -} diff --git a/Specification/src/Ardalis.Specification/Ardalis.Specification.csproj b/Specification/src/Ardalis.Specification/Ardalis.Specification.csproj index 7810f08b..aa7f3106 100644 --- a/Specification/src/Ardalis.Specification/Ardalis.Specification.csproj +++ b/Specification/src/Ardalis.Specification/Ardalis.Specification.csproj @@ -2,40 +2,41 @@ net6.0;netstandard2.0 + 11.0 + enable + + Ardalis.Specification Ardalis.Specification Ardalis.Specification true Steve Smith (@ardalis); Fati Iseni (@fiseni); Scott DePouw; Ardalis.com - https://github.com/ardalis/specification A simple package with a base Specification class, for use in creating queries that work with Repository types. A simple package with a base Specification class, for use in creating queries that work with Repository types. + https://github.com/ardalis/specification https://github.com/ardalis/specification spec;specification;repository;ddd + icon.png 7.0.0 - * Patch 2 by @davidhenley in https://github.com/ardalis/Specification/pull/283 - * Fix `Just the Docs` link in docs home page by @snowfrogdev in https://github.com/ardalis/Specification/pull/293 - * Update url path by @ta1H3n in https://github.com/ardalis/Specification/pull/303 - * Implement SelectMany support by @amdavie in https://github.com/ardalis/Specification/pull/320 - * Add two methods for consuming repositories in scenarios where repositories could be longer lived (e.g. Blazor component Injections) by @jasonsummers in https://github.com/ardalis/Specification/pull/289 - * Added support for AsAsyncEnumerable by @nkz-soft in https://github.com/ardalis/Specification/pull/316 - * Lamadelrae/doc faq ef versions by @Lamadelrae in https://github.com/ardalis/Specification/pull/324 - * Updated projects, drop support for old TFMs. by @fiseni in https://github.com/ardalis/Specification/pull/326 - * Update the search feature to generate parameterized query. by @fiseni in https://github.com/ardalis/Specification/pull/327 - * Add support for extending default evaluator list by @fiseni in https://github.com/ardalis/Specification/pull/328 - * Ardalis/cleanup by @ardalis in https://github.com/ardalis/Specification/pull/332 + * Patch 2 by @davidhenley in https://github.com/ardalis/Specification/pull/283 + * Fix `Just the Docs` link in docs home page by @snowfrogdev in https://github.com/ardalis/Specification/pull/293 + * Update url path by @ta1H3n in https://github.com/ardalis/Specification/pull/303 + * Implement SelectMany support by @amdavie in https://github.com/ardalis/Specification/pull/320 + * Add two methods for consuming repositories in scenarios where repositories could be longer lived (e.g. Blazor component Injections) by @jasonsummers in https://github.com/ardalis/Specification/pull/289 + * Added support for AsAsyncEnumerable by @nkz-soft in https://github.com/ardalis/Specification/pull/316 + * Lamadelrae/doc faq ef versions by @Lamadelrae in https://github.com/ardalis/Specification/pull/324 + * Updated projects, drop support for old TFMs. by @fiseni in https://github.com/ardalis/Specification/pull/326 + * Update the search feature to generate parameterized query. by @fiseni in https://github.com/ardalis/Specification/pull/327 + * Add support for extending default evaluator list by @fiseni in https://github.com/ardalis/Specification/pull/328 + * Ardalis/cleanup by @ardalis in https://github.com/ardalis/Specification/pull/332 - Ardalis.Specification - icon.png true true $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb - 9.0 - enable bin\$(Configuration)\Ardalis.Specification.xml - + @@ -43,4 +44,8 @@ + + + 1701;1702;1591;1573;1712 + diff --git a/Specification/src/Ardalis.Specification/Builder/CacheSpecificationBuilder.cs b/Specification/src/Ardalis.Specification/Builder/CacheSpecificationBuilder.cs index 5378f093..ad0e472a 100644 --- a/Specification/src/Ardalis.Specification/Builder/CacheSpecificationBuilder.cs +++ b/Specification/src/Ardalis.Specification/Builder/CacheSpecificationBuilder.cs @@ -1,19 +1,18 @@ -namespace Ardalis.Specification +namespace Ardalis.Specification; + +public class CacheSpecificationBuilder : ICacheSpecificationBuilder where T : class { - public class CacheSpecificationBuilder : ICacheSpecificationBuilder where T : class - { - public Specification Specification { get; } - public bool IsChainDiscarded { get; set; } + public Specification Specification { get; } + public bool IsChainDiscarded { get; set; } - public CacheSpecificationBuilder(Specification specification) - : this(specification, false) - { - } + public CacheSpecificationBuilder(Specification specification) + : this(specification, false) + { + } - public CacheSpecificationBuilder(Specification specification, bool isChainDiscarded) - { - this.Specification = specification; - this.IsChainDiscarded = isChainDiscarded; - } + public CacheSpecificationBuilder(Specification specification, bool isChainDiscarded) + { + Specification = specification; + IsChainDiscarded = isChainDiscarded; } } diff --git a/Specification/src/Ardalis.Specification/Builder/ICacheSpecificationBuilder.cs b/Specification/src/Ardalis.Specification/Builder/ICacheSpecificationBuilder.cs index 422528e5..c635a211 100644 --- a/Specification/src/Ardalis.Specification/Builder/ICacheSpecificationBuilder.cs +++ b/Specification/src/Ardalis.Specification/Builder/ICacheSpecificationBuilder.cs @@ -1,7 +1,6 @@ -namespace Ardalis.Specification +namespace Ardalis.Specification; + +public interface ICacheSpecificationBuilder : ISpecificationBuilder where T : class { - public interface ICacheSpecificationBuilder : ISpecificationBuilder where T : class - { - bool IsChainDiscarded { get; set; } - } + bool IsChainDiscarded { get; set; } } diff --git a/Specification/src/Ardalis.Specification/Builder/IIncludableSpecificationBuilder.cs b/Specification/src/Ardalis.Specification/Builder/IIncludableSpecificationBuilder.cs index ce7d7bef..df071c3f 100644 --- a/Specification/src/Ardalis.Specification/Builder/IIncludableSpecificationBuilder.cs +++ b/Specification/src/Ardalis.Specification/Builder/IIncludableSpecificationBuilder.cs @@ -1,11 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Text; +namespace Ardalis.Specification; -namespace Ardalis.Specification +public interface IIncludableSpecificationBuilder : ISpecificationBuilder where T : class { - public interface IIncludableSpecificationBuilder : ISpecificationBuilder where T : class - { - bool IsChainDiscarded { get; set; } - } + bool IsChainDiscarded { get; set; } } diff --git a/Specification/src/Ardalis.Specification/Builder/IOrderedSpecificationBuilder.cs b/Specification/src/Ardalis.Specification/Builder/IOrderedSpecificationBuilder.cs index d2bbf175..523c5d79 100644 --- a/Specification/src/Ardalis.Specification/Builder/IOrderedSpecificationBuilder.cs +++ b/Specification/src/Ardalis.Specification/Builder/IOrderedSpecificationBuilder.cs @@ -1,12 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Linq.Expressions; -using System.Text; +namespace Ardalis.Specification; -namespace Ardalis.Specification +public interface IOrderedSpecificationBuilder : ISpecificationBuilder { - public interface IOrderedSpecificationBuilder : ISpecificationBuilder - { - bool IsChainDiscarded { get; set; } - } + bool IsChainDiscarded { get; set; } } diff --git a/Specification/src/Ardalis.Specification/Builder/ISpecificationBuilder.cs b/Specification/src/Ardalis.Specification/Builder/ISpecificationBuilder.cs index 2a5e6b90..505ac8aa 100644 --- a/Specification/src/Ardalis.Specification/Builder/ISpecificationBuilder.cs +++ b/Specification/src/Ardalis.Specification/Builder/ISpecificationBuilder.cs @@ -1,17 +1,11 @@ -using System; -using System.Collections.Generic; -using System.Linq.Expressions; -using System.Text; +namespace Ardalis.Specification; -namespace Ardalis.Specification +public interface ISpecificationBuilder : ISpecificationBuilder { - public interface ISpecificationBuilder : ISpecificationBuilder - { - new Specification Specification { get; } - } + new Specification Specification { get; } +} - public interface ISpecificationBuilder - { - Specification Specification { get; } - } +public interface ISpecificationBuilder +{ + Specification Specification { get; } } diff --git a/Specification/src/Ardalis.Specification/Builder/IncludableBuilderExtensions.cs b/Specification/src/Ardalis.Specification/Builder/IncludableBuilderExtensions.cs index 7fce9a0d..c2cefb19 100644 --- a/Specification/src/Ardalis.Specification/Builder/IncludableBuilderExtensions.cs +++ b/Specification/src/Ardalis.Specification/Builder/IncludableBuilderExtensions.cs @@ -2,56 +2,55 @@ using System.Collections.Generic; using System.Linq.Expressions; -namespace Ardalis.Specification +namespace Ardalis.Specification; + +public static class IncludableBuilderExtensions { - public static class IncludableBuilderExtensions + public static IIncludableSpecificationBuilder ThenInclude( + this IIncludableSpecificationBuilder previousBuilder, + Expression> thenIncludeExpression) + where TEntity : class + => ThenInclude(previousBuilder, thenIncludeExpression, true); + + public static IIncludableSpecificationBuilder ThenInclude( + this IIncludableSpecificationBuilder previousBuilder, + Expression> thenIncludeExpression, + bool condition) + where TEntity : class { - public static IIncludableSpecificationBuilder ThenInclude( - this IIncludableSpecificationBuilder previousBuilder, - Expression> thenIncludeExpression) - where TEntity : class - => ThenInclude(previousBuilder, thenIncludeExpression, true); - - public static IIncludableSpecificationBuilder ThenInclude( - this IIncludableSpecificationBuilder previousBuilder, - Expression> thenIncludeExpression, - bool condition) - where TEntity : class + if (condition && !previousBuilder.IsChainDiscarded) { - if (condition && !previousBuilder.IsChainDiscarded) - { - var info = new IncludeExpressionInfo(thenIncludeExpression, typeof(TEntity), typeof(TProperty), typeof(TPreviousProperty)); + var info = new IncludeExpressionInfo(thenIncludeExpression, typeof(TEntity), typeof(TProperty), typeof(TPreviousProperty)); - ((List)previousBuilder.Specification.IncludeExpressions).Add(info); - } + ((List)previousBuilder.Specification.IncludeExpressions).Add(info); + } - var includeBuilder = new IncludableSpecificationBuilder(previousBuilder.Specification, !condition || previousBuilder.IsChainDiscarded); + var includeBuilder = new IncludableSpecificationBuilder(previousBuilder.Specification, !condition || previousBuilder.IsChainDiscarded); - return includeBuilder; - } + return includeBuilder; + } - public static IIncludableSpecificationBuilder ThenInclude( - this IIncludableSpecificationBuilder> previousBuilder, - Expression> thenIncludeExpression) - where TEntity : class - => ThenInclude(previousBuilder, thenIncludeExpression, true); - - public static IIncludableSpecificationBuilder ThenInclude( - this IIncludableSpecificationBuilder> previousBuilder, - Expression> thenIncludeExpression, - bool condition) - where TEntity : class + public static IIncludableSpecificationBuilder ThenInclude( + this IIncludableSpecificationBuilder> previousBuilder, + Expression> thenIncludeExpression) + where TEntity : class + => ThenInclude(previousBuilder, thenIncludeExpression, true); + + public static IIncludableSpecificationBuilder ThenInclude( + this IIncludableSpecificationBuilder> previousBuilder, + Expression> thenIncludeExpression, + bool condition) + where TEntity : class + { + if (condition && !previousBuilder.IsChainDiscarded) { - if (condition && !previousBuilder.IsChainDiscarded) - { - var info = new IncludeExpressionInfo(thenIncludeExpression, typeof(TEntity), typeof(TProperty), typeof(IEnumerable)); + var info = new IncludeExpressionInfo(thenIncludeExpression, typeof(TEntity), typeof(TProperty), typeof(IEnumerable)); - ((List)previousBuilder.Specification.IncludeExpressions).Add(info); - } + ((List)previousBuilder.Specification.IncludeExpressions).Add(info); + } - var includeBuilder = new IncludableSpecificationBuilder(previousBuilder.Specification, !condition || previousBuilder.IsChainDiscarded); + var includeBuilder = new IncludableSpecificationBuilder(previousBuilder.Specification, !condition || previousBuilder.IsChainDiscarded); - return includeBuilder; - } + return includeBuilder; } } diff --git a/Specification/src/Ardalis.Specification/Builder/IncludableSpecificationBuilder.cs b/Specification/src/Ardalis.Specification/Builder/IncludableSpecificationBuilder.cs index 18a5999a..f89c76ed 100644 --- a/Specification/src/Ardalis.Specification/Builder/IncludableSpecificationBuilder.cs +++ b/Specification/src/Ardalis.Specification/Builder/IncludableSpecificationBuilder.cs @@ -1,23 +1,18 @@ -using System; -using System.Collections.Generic; -using System.Text; +namespace Ardalis.Specification; -namespace Ardalis.Specification +public class IncludableSpecificationBuilder : IIncludableSpecificationBuilder where T : class { - public class IncludableSpecificationBuilder : IIncludableSpecificationBuilder where T : class - { - public Specification Specification { get; } - public bool IsChainDiscarded { get; set; } + public Specification Specification { get; } + public bool IsChainDiscarded { get; set; } - public IncludableSpecificationBuilder(Specification specification) - : this(specification, false) - { - } + public IncludableSpecificationBuilder(Specification specification) + : this(specification, false) + { + } - public IncludableSpecificationBuilder(Specification specification, bool isChainDiscarded) - { - this.Specification = specification; - this.IsChainDiscarded = isChainDiscarded; - } + public IncludableSpecificationBuilder(Specification specification, bool isChainDiscarded) + { + Specification = specification; + IsChainDiscarded = isChainDiscarded; } } diff --git a/Specification/src/Ardalis.Specification/Builder/OrderedBuilderExtensions.cs b/Specification/src/Ardalis.Specification/Builder/OrderedBuilderExtensions.cs index 62232372..3ab76eae 100644 --- a/Specification/src/Ardalis.Specification/Builder/OrderedBuilderExtensions.cs +++ b/Specification/src/Ardalis.Specification/Builder/OrderedBuilderExtensions.cs @@ -1,54 +1,52 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Linq.Expressions; -namespace Ardalis.Specification +namespace Ardalis.Specification; + +public static class OrderedBuilderExtensions { - public static class OrderedBuilderExtensions - { - public static IOrderedSpecificationBuilder ThenBy( - this IOrderedSpecificationBuilder orderedBuilder, - Expression> orderExpression) - => ThenBy(orderedBuilder, orderExpression, true); + public static IOrderedSpecificationBuilder ThenBy( + this IOrderedSpecificationBuilder orderedBuilder, + Expression> orderExpression) + => ThenBy(orderedBuilder, orderExpression, true); - public static IOrderedSpecificationBuilder ThenBy( - this IOrderedSpecificationBuilder orderedBuilder, - Expression> orderExpression, - bool condition) + public static IOrderedSpecificationBuilder ThenBy( + this IOrderedSpecificationBuilder orderedBuilder, + Expression> orderExpression, + bool condition) + { + if (condition && !orderedBuilder.IsChainDiscarded) { - if (condition && !orderedBuilder.IsChainDiscarded) - { - ((List>)orderedBuilder.Specification.OrderExpressions).Add(new OrderExpressionInfo(orderExpression, OrderTypeEnum.ThenBy)); - } - else - { - orderedBuilder.IsChainDiscarded = true; - } - - return orderedBuilder; + ((List>)orderedBuilder.Specification.OrderExpressions).Add(new OrderExpressionInfo(orderExpression, OrderTypeEnum.ThenBy)); + } + else + { + orderedBuilder.IsChainDiscarded = true; } - public static IOrderedSpecificationBuilder ThenByDescending( - this IOrderedSpecificationBuilder orderedBuilder, - Expression> orderExpression) - => ThenByDescending(orderedBuilder, orderExpression, true); + return orderedBuilder; + } - public static IOrderedSpecificationBuilder ThenByDescending( - this IOrderedSpecificationBuilder orderedBuilder, - Expression> orderExpression, - bool condition) - { - if (condition && !orderedBuilder.IsChainDiscarded) - { - ((List>)orderedBuilder.Specification.OrderExpressions).Add(new OrderExpressionInfo(orderExpression, OrderTypeEnum.ThenByDescending)); - } - else - { - orderedBuilder.IsChainDiscarded = true; - } + public static IOrderedSpecificationBuilder ThenByDescending( + this IOrderedSpecificationBuilder orderedBuilder, + Expression> orderExpression) + => ThenByDescending(orderedBuilder, orderExpression, true); - return orderedBuilder; + public static IOrderedSpecificationBuilder ThenByDescending( + this IOrderedSpecificationBuilder orderedBuilder, + Expression> orderExpression, + bool condition) + { + if (condition && !orderedBuilder.IsChainDiscarded) + { + ((List>)orderedBuilder.Specification.OrderExpressions).Add(new OrderExpressionInfo(orderExpression, OrderTypeEnum.ThenByDescending)); } + else + { + orderedBuilder.IsChainDiscarded = true; + } + + return orderedBuilder; } } diff --git a/Specification/src/Ardalis.Specification/Builder/OrderedSpecificationBuilder.cs b/Specification/src/Ardalis.Specification/Builder/OrderedSpecificationBuilder.cs index 22e935ec..66224d9a 100644 --- a/Specification/src/Ardalis.Specification/Builder/OrderedSpecificationBuilder.cs +++ b/Specification/src/Ardalis.Specification/Builder/OrderedSpecificationBuilder.cs @@ -1,24 +1,18 @@ -using System; -using System.Collections.Generic; -using System.Linq.Expressions; -using System.Text; +namespace Ardalis.Specification; -namespace Ardalis.Specification +public class OrderedSpecificationBuilder : IOrderedSpecificationBuilder { - public class OrderedSpecificationBuilder : IOrderedSpecificationBuilder - { - public Specification Specification { get; } - public bool IsChainDiscarded { get; set; } + public Specification Specification { get; } + public bool IsChainDiscarded { get; set; } - public OrderedSpecificationBuilder(Specification specification) - : this(specification, false) - { - } + public OrderedSpecificationBuilder(Specification specification) + : this(specification, false) + { + } - public OrderedSpecificationBuilder(Specification specification, bool isChainDiscarded) - { - this.Specification = specification; - this.IsChainDiscarded = isChainDiscarded; - } + public OrderedSpecificationBuilder(Specification specification, bool isChainDiscarded) + { + Specification = specification; + IsChainDiscarded = isChainDiscarded; } } diff --git a/Specification/src/Ardalis.Specification/Builder/SpecificationBuilder.cs b/Specification/src/Ardalis.Specification/Builder/SpecificationBuilder.cs index a149aa13..711c8725 100644 --- a/Specification/src/Ardalis.Specification/Builder/SpecificationBuilder.cs +++ b/Specification/src/Ardalis.Specification/Builder/SpecificationBuilder.cs @@ -1,28 +1,22 @@ -using System; -using System.Collections.Generic; -using System.Linq.Expressions; -using System.Text; +namespace Ardalis.Specification; -namespace Ardalis.Specification +public class SpecificationBuilder : SpecificationBuilder, ISpecificationBuilder { - public class SpecificationBuilder : SpecificationBuilder, ISpecificationBuilder - { - public new Specification Specification { get; } + public new Specification Specification { get; } - public SpecificationBuilder(Specification specification) - : base(specification) - { - this.Specification = specification; - } + public SpecificationBuilder(Specification specification) + : base(specification) + { + Specification = specification; } +} - public class SpecificationBuilder : ISpecificationBuilder - { - public Specification Specification { get; } +public class SpecificationBuilder : ISpecificationBuilder +{ + public Specification Specification { get; } - public SpecificationBuilder(Specification specification) - { - this.Specification = specification; - } + public SpecificationBuilder(Specification specification) + { + Specification = specification; } } diff --git a/Specification/src/Ardalis.Specification/Builder/SpecificationBuilderExtensions.cs b/Specification/src/Ardalis.Specification/Builder/SpecificationBuilderExtensions.cs index b3da0032..0c787420 100644 --- a/Specification/src/Ardalis.Specification/Builder/SpecificationBuilderExtensions.cs +++ b/Specification/src/Ardalis.Specification/Builder/SpecificationBuilderExtensions.cs @@ -2,537 +2,536 @@ using System.Collections.Generic; using System.Linq.Expressions; -namespace Ardalis.Specification +namespace Ardalis.Specification; + +public static class SpecificationBuilderExtensions { - public static class SpecificationBuilderExtensions + /// + /// Specify a predicate that will be applied to the query + /// + /// + /// + /// + public static ISpecificationBuilder Where( + this ISpecificationBuilder specificationBuilder, + Expression> criteria) + => Where(specificationBuilder, criteria, true); + + /// + /// Specify a predicate that will be applied to the query + /// + /// + /// + /// + /// If false, the criteria won't be added. + public static ISpecificationBuilder Where( + this ISpecificationBuilder specificationBuilder, + Expression> criteria, + bool condition) { - /// - /// Specify a predicate that will be applied to the query - /// - /// - /// - /// - public static ISpecificationBuilder Where( - this ISpecificationBuilder specificationBuilder, - Expression> criteria) - => Where(specificationBuilder, criteria, true); - - /// - /// Specify a predicate that will be applied to the query - /// - /// - /// - /// - /// If false, the criteria won't be added. - public static ISpecificationBuilder Where( - this ISpecificationBuilder specificationBuilder, - Expression> criteria, - bool condition) + if (condition) { - if (condition) - { - ((List>)specificationBuilder.Specification.WhereExpressions).Add(new WhereExpressionInfo(criteria)); - } - - return specificationBuilder; + ((List>)specificationBuilder.Specification.WhereExpressions).Add(new WhereExpressionInfo(criteria)); } - /// - /// Specify the query result will be ordered by in an ascending order - /// - /// - /// - /// - public static IOrderedSpecificationBuilder OrderBy( - this ISpecificationBuilder specificationBuilder, - Expression> orderExpression) - => OrderBy(specificationBuilder, orderExpression, true); - - /// - /// Specify the query result will be ordered by in an ascending order - /// - /// - /// - /// - /// If false, the expression won't be added. The whole Order chain will be discarded. - public static IOrderedSpecificationBuilder OrderBy( - this ISpecificationBuilder specificationBuilder, - Expression> orderExpression, - bool condition) - { - if (condition) - { - ((List>)specificationBuilder.Specification.OrderExpressions).Add(new OrderExpressionInfo(orderExpression, OrderTypeEnum.OrderBy)); - } - - var orderedSpecificationBuilder = new OrderedSpecificationBuilder(specificationBuilder.Specification, !condition); - - return orderedSpecificationBuilder; - } + return specificationBuilder; + } - /// - /// Specify the query result will be ordered by in a descending order - /// - /// - /// - /// - public static IOrderedSpecificationBuilder OrderByDescending( - this ISpecificationBuilder specificationBuilder, - Expression> orderExpression) - => OrderByDescending(specificationBuilder, orderExpression, true); - - /// - /// Specify the query result will be ordered by in a descending order - /// - /// - /// - /// - /// If false, the expression won't be added. The whole Order chain will be discarded. - public static IOrderedSpecificationBuilder OrderByDescending( - this ISpecificationBuilder specificationBuilder, - Expression> orderExpression, - bool condition) + /// + /// Specify the query result will be ordered by in an ascending order + /// + /// + /// + /// + public static IOrderedSpecificationBuilder OrderBy( + this ISpecificationBuilder specificationBuilder, + Expression> orderExpression) + => OrderBy(specificationBuilder, orderExpression, true); + + /// + /// Specify the query result will be ordered by in an ascending order + /// + /// + /// + /// + /// If false, the expression won't be added. The whole Order chain will be discarded. + public static IOrderedSpecificationBuilder OrderBy( + this ISpecificationBuilder specificationBuilder, + Expression> orderExpression, + bool condition) + { + if (condition) { - if (condition) - { - ((List>)specificationBuilder.Specification.OrderExpressions).Add(new OrderExpressionInfo(orderExpression, OrderTypeEnum.OrderByDescending)); - } - - var orderedSpecificationBuilder = new OrderedSpecificationBuilder(specificationBuilder.Specification, !condition); - - return orderedSpecificationBuilder; + ((List>)specificationBuilder.Specification.OrderExpressions).Add(new OrderExpressionInfo(orderExpression, OrderTypeEnum.OrderBy)); } - /// - /// Specify an include expression. - /// This information is utilized to build Include function in the query, which ORM tools like Entity Framework use - /// to include related entities (via navigation properties) in the query result. - /// - /// - /// - /// - /// - public static IIncludableSpecificationBuilder Include( - this ISpecificationBuilder specificationBuilder, - Expression> includeExpression) where T : class - => Include(specificationBuilder, includeExpression, true); - - /// - /// Specify an include expression. - /// This information is utilized to build Include function in the query, which ORM tools like Entity Framework use - /// to include related entities (via navigation properties) in the query result. - /// - /// - /// - /// - /// - /// If false, the expression won't be added. The whole Include chain will be discarded. - public static IIncludableSpecificationBuilder Include( - this ISpecificationBuilder specificationBuilder, - Expression> includeExpression, - bool condition) where T : class - { - if (condition) - { - var info = new IncludeExpressionInfo(includeExpression, typeof(T), typeof(TProperty)); - - ((List)specificationBuilder.Specification.IncludeExpressions).Add(info); - } + var orderedSpecificationBuilder = new OrderedSpecificationBuilder(specificationBuilder.Specification, !condition); - var includeBuilder = new IncludableSpecificationBuilder(specificationBuilder.Specification, !condition); + return orderedSpecificationBuilder; + } - return includeBuilder; + /// + /// Specify the query result will be ordered by in a descending order + /// + /// + /// + /// + public static IOrderedSpecificationBuilder OrderByDescending( + this ISpecificationBuilder specificationBuilder, + Expression> orderExpression) + => OrderByDescending(specificationBuilder, orderExpression, true); + + /// + /// Specify the query result will be ordered by in a descending order + /// + /// + /// + /// + /// If false, the expression won't be added. The whole Order chain will be discarded. + public static IOrderedSpecificationBuilder OrderByDescending( + this ISpecificationBuilder specificationBuilder, + Expression> orderExpression, + bool condition) + { + if (condition) + { + ((List>)specificationBuilder.Specification.OrderExpressions).Add(new OrderExpressionInfo(orderExpression, OrderTypeEnum.OrderByDescending)); } - /// - /// Specify a collection of navigation properties, as strings, to include in the query. - /// - /// - /// - /// - public static ISpecificationBuilder Include( - this ISpecificationBuilder specificationBuilder, - string includeString) where T : class - => Include(specificationBuilder, includeString, true); - - /// - /// Specify a collection of navigation properties, as strings, to include in the query. - /// - /// - /// - /// - /// If false, the include expression won't be added. - public static ISpecificationBuilder Include( - this ISpecificationBuilder specificationBuilder, - string includeString, - bool condition) where T : class - { - if (condition) - { - ((List)specificationBuilder.Specification.IncludeStrings).Add(includeString); - } + var orderedSpecificationBuilder = new OrderedSpecificationBuilder(specificationBuilder.Specification, !condition); - return specificationBuilder; - } + return orderedSpecificationBuilder; + } - /// - /// Specify a 'SQL LIKE' operations for search purposes - /// - /// - /// - /// the property to apply the SQL LIKE against - /// the value to use for the SQL LIKE - /// the index used to group sets of Selectors and SearchTerms together - public static ISpecificationBuilder Search( - this ISpecificationBuilder specificationBuilder, - Expression> selector, - string searchTerm, - int searchGroup = 1) where T : class - => Search(specificationBuilder, selector, searchTerm, true, searchGroup); - - /// - /// Specify a 'SQL LIKE' operations for search purposes - /// - /// - /// - /// the property to apply the SQL LIKE against - /// the value to use for the SQL LIKE - /// If false, the expression won't be added. - /// the index used to group sets of Selectors and SearchTerms together - public static ISpecificationBuilder Search( - this ISpecificationBuilder specificationBuilder, - Expression> selector, - string searchTerm, - bool condition, - int searchGroup = 1) where T : class + /// + /// Specify an include expression. + /// This information is utilized to build Include function in the query, which ORM tools like Entity Framework use + /// to include related entities (via navigation properties) in the query result. + /// + /// + /// + /// + /// + public static IIncludableSpecificationBuilder Include( + this ISpecificationBuilder specificationBuilder, + Expression> includeExpression) where T : class + => Include(specificationBuilder, includeExpression, true); + + /// + /// Specify an include expression. + /// This information is utilized to build Include function in the query, which ORM tools like Entity Framework use + /// to include related entities (via navigation properties) in the query result. + /// + /// + /// + /// + /// + /// If false, the expression won't be added. The whole Include chain will be discarded. + public static IIncludableSpecificationBuilder Include( + this ISpecificationBuilder specificationBuilder, + Expression> includeExpression, + bool condition) where T : class + { + if (condition) { - if (condition) - { - ((List>)specificationBuilder.Specification.SearchCriterias).Add(new SearchExpressionInfo(selector, searchTerm, searchGroup)); - } + var info = new IncludeExpressionInfo(includeExpression, typeof(T), typeof(TProperty)); - return specificationBuilder; + ((List)specificationBuilder.Specification.IncludeExpressions).Add(info); } - /// - /// Specify the number of elements to return. - /// - /// - /// number of elements to take - public static ISpecificationBuilder Take( - this ISpecificationBuilder specificationBuilder, - int take) - => Take(specificationBuilder, take, true); - - /// - /// Specify the number of elements to return. - /// - /// - /// number of elements to take - /// If false, the value will be discarded. - public static ISpecificationBuilder Take( - this ISpecificationBuilder specificationBuilder, - int take, - bool condition) - { - if (condition) - { - if (specificationBuilder.Specification.Take != null) throw new DuplicateTakeException(); - - specificationBuilder.Specification.Take = take; - } + var includeBuilder = new IncludableSpecificationBuilder(specificationBuilder.Specification, !condition); - return specificationBuilder; - } + return includeBuilder; + } - /// - /// Specify the number of elements to skip before returning the remaining elements. - /// - /// - /// - /// number of elements to skip - public static ISpecificationBuilder Skip( - this ISpecificationBuilder specificationBuilder, - int skip) - => Skip(specificationBuilder, skip, true); - - /// - /// Specify the number of elements to skip before returning the remaining elements. - /// - /// - /// - /// number of elements to skip - /// If false, the value will be discarded. - public static ISpecificationBuilder Skip( - this ISpecificationBuilder specificationBuilder, - int skip, - bool condition) + /// + /// Specify a collection of navigation properties, as strings, to include in the query. + /// + /// + /// + /// + public static ISpecificationBuilder Include( + this ISpecificationBuilder specificationBuilder, + string includeString) where T : class + => Include(specificationBuilder, includeString, true); + + /// + /// Specify a collection of navigation properties, as strings, to include in the query. + /// + /// + /// + /// + /// If false, the include expression won't be added. + public static ISpecificationBuilder Include( + this ISpecificationBuilder specificationBuilder, + string includeString, + bool condition) where T : class + { + if (condition) { - if (condition) - { - if (specificationBuilder.Specification.Skip != null) throw new DuplicateSkipException(); + ((List)specificationBuilder.Specification.IncludeStrings).Add(includeString); + } - specificationBuilder.Specification.Skip = skip; - } + return specificationBuilder; + } - return specificationBuilder; + /// + /// Specify a 'SQL LIKE' operations for search purposes + /// + /// + /// + /// the property to apply the SQL LIKE against + /// the value to use for the SQL LIKE + /// the index used to group sets of Selectors and SearchTerms together + public static ISpecificationBuilder Search( + this ISpecificationBuilder specificationBuilder, + Expression> selector, + string searchTerm, + int searchGroup = 1) where T : class + => Search(specificationBuilder, selector, searchTerm, true, searchGroup); + + /// + /// Specify a 'SQL LIKE' operations for search purposes + /// + /// + /// + /// the property to apply the SQL LIKE against + /// the value to use for the SQL LIKE + /// If false, the expression won't be added. + /// the index used to group sets of Selectors and SearchTerms together + public static ISpecificationBuilder Search( + this ISpecificationBuilder specificationBuilder, + Expression> selector, + string searchTerm, + bool condition, + int searchGroup = 1) where T : class + { + if (condition) + { + ((List>)specificationBuilder.Specification.SearchCriterias).Add(new SearchExpressionInfo(selector, searchTerm, searchGroup)); } - /// - /// Specify a transform function to apply to the element - /// to produce another element. - /// - public static ISpecificationBuilder Select( - this ISpecificationBuilder specificationBuilder, - Expression> selector) + return specificationBuilder; + } + + /// + /// Specify the number of elements to return. + /// + /// + /// number of elements to take + public static ISpecificationBuilder Take( + this ISpecificationBuilder specificationBuilder, + int take) + => Take(specificationBuilder, take, true); + + /// + /// Specify the number of elements to return. + /// + /// + /// number of elements to take + /// If false, the value will be discarded. + public static ISpecificationBuilder Take( + this ISpecificationBuilder specificationBuilder, + int take, + bool condition) + { + if (condition) { - specificationBuilder.Specification.Selector = selector; + if (specificationBuilder.Specification.Take != null) throw new DuplicateTakeException(); - return specificationBuilder; + specificationBuilder.Specification.Take = take; } - /// - /// Specify a transform function to apply to the element - /// to produce a flattened sequence of elements. - /// - public static ISpecificationBuilder SelectMany( - this ISpecificationBuilder specificationBuilder, - Expression>> selector) + return specificationBuilder; + } + + /// + /// Specify the number of elements to skip before returning the remaining elements. + /// + /// + /// + /// number of elements to skip + public static ISpecificationBuilder Skip( + this ISpecificationBuilder specificationBuilder, + int skip) + => Skip(specificationBuilder, skip, true); + + /// + /// Specify the number of elements to skip before returning the remaining elements. + /// + /// + /// + /// number of elements to skip + /// If false, the value will be discarded. + public static ISpecificationBuilder Skip( + this ISpecificationBuilder specificationBuilder, + int skip, + bool condition) + { + if (condition) { - specificationBuilder.Specification.SelectorMany = selector; + if (specificationBuilder.Specification.Skip != null) throw new DuplicateSkipException(); - return specificationBuilder; + specificationBuilder.Specification.Skip = skip; } - /// - /// Specify a transform function to apply to the result of the query - /// and returns the same type - /// - public static ISpecificationBuilder PostProcessingAction( - this ISpecificationBuilder specificationBuilder, - Func, IEnumerable> predicate) - { - specificationBuilder.Specification.PostProcessingAction = predicate; + return specificationBuilder; + } - return specificationBuilder; - } + /// + /// Specify a transform function to apply to the element + /// to produce another element. + /// + public static ISpecificationBuilder Select( + this ISpecificationBuilder specificationBuilder, + Expression> selector) + { + specificationBuilder.Specification.Selector = selector; - /// - /// Specify a transform function to apply to the result of the query. - /// and returns another type - /// - public static ISpecificationBuilder PostProcessingAction( - this ISpecificationBuilder specificationBuilder, - Func, IEnumerable> predicate) - { - specificationBuilder.Specification.PostProcessingAction = predicate; + return specificationBuilder; + } - return specificationBuilder; - } + /// + /// Specify a transform function to apply to the element + /// to produce a flattened sequence of elements. + /// + public static ISpecificationBuilder SelectMany( + this ISpecificationBuilder specificationBuilder, + Expression>> selector) + { + specificationBuilder.Specification.SelectorMany = selector; - /// - /// Must be called after specifying criteria - /// - /// - /// Any arguments used in defining the specification - public static ICacheSpecificationBuilder EnableCache( - this ISpecificationBuilder specificationBuilder, - string specificationName, - params object[] args) where T : class - => EnableCache(specificationBuilder, specificationName, true, args); - - /// - /// Must be called after specifying criteria - /// - /// - /// Any arguments used in defining the specification - /// If false, the caching won't be enabled. - public static ICacheSpecificationBuilder EnableCache( - this ISpecificationBuilder specificationBuilder, - string specificationName, - bool condition, - params object[] args) where T : class - { - if (condition) - { - if (string.IsNullOrEmpty(specificationName)) - { - throw new ArgumentException($"Required input {specificationName} was null or empty.", specificationName); - } + return specificationBuilder; + } - specificationBuilder.Specification.CacheKey = $"{specificationName}-{string.Join("-", args)}"; + /// + /// Specify a transform function to apply to the result of the query + /// and returns the same type + /// + public static ISpecificationBuilder PostProcessingAction( + this ISpecificationBuilder specificationBuilder, + Func, IEnumerable> predicate) + { + specificationBuilder.Specification.PostProcessingAction = predicate; - specificationBuilder.Specification.CacheEnabled = true; - } + return specificationBuilder; + } - var cacheBuilder = new CacheSpecificationBuilder(specificationBuilder.Specification, !condition); + /// + /// Specify a transform function to apply to the result of the query. + /// and returns another type + /// + public static ISpecificationBuilder PostProcessingAction( + this ISpecificationBuilder specificationBuilder, + Func, IEnumerable> predicate) + { + specificationBuilder.Specification.PostProcessingAction = predicate; - return cacheBuilder; - } + return specificationBuilder; + } - /// - /// If the entity instances are modified, this will be detected - /// by the change tracker. - /// - /// - public static ISpecificationBuilder AsTracking( - this ISpecificationBuilder specificationBuilder) where T : class - => AsTracking(specificationBuilder, true); - - /// - /// If the entity instances are modified, this will be detected - /// by the change tracker. - /// - /// - /// If false, the setting will be discarded. - public static ISpecificationBuilder AsTracking( - this ISpecificationBuilder specificationBuilder, - bool condition) where T : class + /// + /// Must be called after specifying criteria + /// + /// + /// Any arguments used in defining the specification + public static ICacheSpecificationBuilder EnableCache( + this ISpecificationBuilder specificationBuilder, + string specificationName, + params object[] args) where T : class + => EnableCache(specificationBuilder, specificationName, true, args); + + /// + /// Must be called after specifying criteria + /// + /// + /// Any arguments used in defining the specification + /// If false, the caching won't be enabled. + public static ICacheSpecificationBuilder EnableCache( + this ISpecificationBuilder specificationBuilder, + string specificationName, + bool condition, + params object[] args) where T : class + { + if (condition) { - if (condition) + if (string.IsNullOrEmpty(specificationName)) { - specificationBuilder.Specification.AsNoTracking = false; - specificationBuilder.Specification.AsNoTrackingWithIdentityResolution = false; - specificationBuilder.Specification.AsTracking = true; + throw new ArgumentException($"Required input {specificationName} was null or empty.", specificationName); } - return specificationBuilder; + specificationBuilder.Specification.CacheKey = $"{specificationName}-{string.Join("-", args)}"; + + specificationBuilder.Specification.CacheEnabled = true; } - /// - /// If the entity instances are modified, this will not be detected - /// by the change tracker. - /// - /// - public static ISpecificationBuilder AsNoTracking( - this ISpecificationBuilder specificationBuilder) where T : class - => AsNoTracking(specificationBuilder, true); - - /// - /// If the entity instances are modified, this will not be detected - /// by the change tracker. - /// - /// - /// If false, the setting will be discarded. - public static ISpecificationBuilder AsNoTracking( - this ISpecificationBuilder specificationBuilder, - bool condition) where T : class - { - if (condition) - { - specificationBuilder.Specification.AsTracking = false; - specificationBuilder.Specification.AsNoTrackingWithIdentityResolution = false; - specificationBuilder.Specification.AsNoTracking = true; - } + var cacheBuilder = new CacheSpecificationBuilder(specificationBuilder.Specification, !condition); - return specificationBuilder; - } + return cacheBuilder; + } - /// - /// The generated sql query will be split into multiple SQL queries - /// - /// - /// This feature was introduced in EF Core 5.0. It only works when using Include - /// for more info: https://docs.microsoft.com/en-us/ef/core/querying/single-split-queries - /// - /// - /// - public static ISpecificationBuilder AsSplitQuery( - this ISpecificationBuilder specificationBuilder) where T : class - => AsSplitQuery(specificationBuilder, true); - - /// - /// The generated sql query will be split into multiple SQL queries - /// - /// - /// This feature was introduced in EF Core 5.0. It only works when using Include - /// for more info: https://docs.microsoft.com/en-us/ef/core/querying/single-split-queries - /// - /// - /// - /// If false, the setting will be discarded. - public static ISpecificationBuilder AsSplitQuery( - this ISpecificationBuilder specificationBuilder, - bool condition) where T : class + /// + /// If the entity instances are modified, this will be detected + /// by the change tracker. + /// + /// + public static ISpecificationBuilder AsTracking( + this ISpecificationBuilder specificationBuilder) where T : class + => AsTracking(specificationBuilder, true); + + /// + /// If the entity instances are modified, this will be detected + /// by the change tracker. + /// + /// + /// If false, the setting will be discarded. + public static ISpecificationBuilder AsTracking( + this ISpecificationBuilder specificationBuilder, + bool condition) where T : class + { + if (condition) { - if (condition) - { - specificationBuilder.Specification.AsSplitQuery = true; - } - - return specificationBuilder; + specificationBuilder.Specification.AsNoTracking = false; + specificationBuilder.Specification.AsNoTrackingWithIdentityResolution = false; + specificationBuilder.Specification.AsTracking = true; } - /// - /// The query will then keep track of returned instances - /// (without tracking them in the normal way) - /// and ensure no duplicates are created in the query results - /// - /// - /// for more info: https://docs.microsoft.com/en-us/ef/core/change-tracking/identity-resolution#identity-resolution-and-queries - /// - /// - /// - public static ISpecificationBuilder AsNoTrackingWithIdentityResolution( - this ISpecificationBuilder specificationBuilder) where T : class - => AsNoTrackingWithIdentityResolution(specificationBuilder, true); - - /// - /// The query will then keep track of returned instances - /// (without tracking them in the normal way) - /// and ensure no duplicates are created in the query results - /// - /// - /// for more info: https://docs.microsoft.com/en-us/ef/core/change-tracking/identity-resolution#identity-resolution-and-queries - /// - /// - /// - /// If false, the setting will be discarded. - public static ISpecificationBuilder AsNoTrackingWithIdentityResolution( - this ISpecificationBuilder specificationBuilder, - bool condition) where T : class + return specificationBuilder; + } + + /// + /// If the entity instances are modified, this will not be detected + /// by the change tracker. + /// + /// + public static ISpecificationBuilder AsNoTracking( + this ISpecificationBuilder specificationBuilder) where T : class + => AsNoTracking(specificationBuilder, true); + + /// + /// If the entity instances are modified, this will not be detected + /// by the change tracker. + /// + /// + /// If false, the setting will be discarded. + public static ISpecificationBuilder AsNoTracking( + this ISpecificationBuilder specificationBuilder, + bool condition) where T : class + { + if (condition) { - if (condition) - { - specificationBuilder.Specification.AsTracking = false; - specificationBuilder.Specification.AsNoTracking = false; - specificationBuilder.Specification.AsNoTrackingWithIdentityResolution = true; - } + specificationBuilder.Specification.AsTracking = false; + specificationBuilder.Specification.AsNoTrackingWithIdentityResolution = false; + specificationBuilder.Specification.AsNoTracking = true; + } - return specificationBuilder; + return specificationBuilder; + } + + /// + /// The generated sql query will be split into multiple SQL queries + /// + /// + /// This feature was introduced in EF Core 5.0. It only works when using Include + /// for more info: https://docs.microsoft.com/en-us/ef/core/querying/single-split-queries + /// + /// + /// + public static ISpecificationBuilder AsSplitQuery( + this ISpecificationBuilder specificationBuilder) where T : class + => AsSplitQuery(specificationBuilder, true); + + /// + /// The generated sql query will be split into multiple SQL queries + /// + /// + /// This feature was introduced in EF Core 5.0. It only works when using Include + /// for more info: https://docs.microsoft.com/en-us/ef/core/querying/single-split-queries + /// + /// + /// + /// If false, the setting will be discarded. + public static ISpecificationBuilder AsSplitQuery( + this ISpecificationBuilder specificationBuilder, + bool condition) where T : class + { + if (condition) + { + specificationBuilder.Specification.AsSplitQuery = true; } - /// - /// 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 - => IgnoreQueryFilters(specificationBuilder, true); - - /// - /// The query will ignore the defined global query filters - /// - /// - /// for more info: https://docs.microsoft.com/en-us/ef/core/querying/filters - /// - /// - /// - /// If false, the setting will be discarded. - public static ISpecificationBuilder IgnoreQueryFilters( - this ISpecificationBuilder specificationBuilder, - bool condition) where T : class + return specificationBuilder; + } + + /// + /// The query will then keep track of returned instances + /// (without tracking them in the normal way) + /// and ensure no duplicates are created in the query results + /// + /// + /// for more info: https://docs.microsoft.com/en-us/ef/core/change-tracking/identity-resolution#identity-resolution-and-queries + /// + /// + /// + public static ISpecificationBuilder AsNoTrackingWithIdentityResolution( + this ISpecificationBuilder specificationBuilder) where T : class + => AsNoTrackingWithIdentityResolution(specificationBuilder, true); + + /// + /// The query will then keep track of returned instances + /// (without tracking them in the normal way) + /// and ensure no duplicates are created in the query results + /// + /// + /// for more info: https://docs.microsoft.com/en-us/ef/core/change-tracking/identity-resolution#identity-resolution-and-queries + /// + /// + /// + /// If false, the setting will be discarded. + public static ISpecificationBuilder AsNoTrackingWithIdentityResolution( + this ISpecificationBuilder specificationBuilder, + bool condition) where T : class + { + if (condition) { - if (condition) - { - specificationBuilder.Specification.IgnoreQueryFilters = true; - } + specificationBuilder.Specification.AsTracking = false; + specificationBuilder.Specification.AsNoTracking = false; + specificationBuilder.Specification.AsNoTrackingWithIdentityResolution = true; + } + + return specificationBuilder; + } - 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 + => IgnoreQueryFilters(specificationBuilder, true); + + /// + /// The query will ignore the defined global query filters + /// + /// + /// for more info: https://docs.microsoft.com/en-us/ef/core/querying/filters + /// + /// + /// + /// If false, the setting will be discarded. + public static ISpecificationBuilder IgnoreQueryFilters( + this ISpecificationBuilder specificationBuilder, + bool condition) where T : class + { + if (condition) + { + specificationBuilder.Specification.IgnoreQueryFilters = true; } + + return specificationBuilder; } } diff --git a/Specification/src/Ardalis.Specification/Evaluators/IEvaluator.cs b/Specification/src/Ardalis.Specification/Evaluators/IEvaluator.cs index 4f4435c0..0b05e55b 100644 --- a/Specification/src/Ardalis.Specification/Evaluators/IEvaluator.cs +++ b/Specification/src/Ardalis.Specification/Evaluators/IEvaluator.cs @@ -1,14 +1,10 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; +using System.Linq; -namespace Ardalis.Specification +namespace Ardalis.Specification; + +public interface IEvaluator { - public interface IEvaluator - { - bool IsCriteriaEvaluator { get; } + bool IsCriteriaEvaluator { get; } - IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class; - } + IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class; } diff --git a/Specification/src/Ardalis.Specification/Evaluators/IInMemoryEvaluator.cs b/Specification/src/Ardalis.Specification/Evaluators/IInMemoryEvaluator.cs index 5dafa207..082fa031 100644 --- a/Specification/src/Ardalis.Specification/Evaluators/IInMemoryEvaluator.cs +++ b/Specification/src/Ardalis.Specification/Evaluators/IInMemoryEvaluator.cs @@ -1,12 +1,8 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; +using System.Collections.Generic; -namespace Ardalis.Specification +namespace Ardalis.Specification; + +public interface IInMemoryEvaluator { - public interface IInMemoryEvaluator - { - IEnumerable Evaluate(IEnumerable query, ISpecification specification); - } + IEnumerable Evaluate(IEnumerable query, ISpecification specification); } diff --git a/Specification/src/Ardalis.Specification/Evaluators/IInMemorySpecificationEvaluator.cs b/Specification/src/Ardalis.Specification/Evaluators/IInMemorySpecificationEvaluator.cs index b44f2112..a941fb4b 100644 --- a/Specification/src/Ardalis.Specification/Evaluators/IInMemorySpecificationEvaluator.cs +++ b/Specification/src/Ardalis.Specification/Evaluators/IInMemorySpecificationEvaluator.cs @@ -1,13 +1,9 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; +using System.Collections.Generic; -namespace Ardalis.Specification +namespace Ardalis.Specification; + +public interface IInMemorySpecificationEvaluator { - public interface IInMemorySpecificationEvaluator - { - IEnumerable Evaluate(IEnumerable source, ISpecification specification); - IEnumerable Evaluate(IEnumerable source, ISpecification specification); - } + IEnumerable Evaluate(IEnumerable source, ISpecification specification); + IEnumerable Evaluate(IEnumerable source, ISpecification specification); } diff --git a/Specification/src/Ardalis.Specification/Evaluators/ISpecificationEvaluator.cs b/Specification/src/Ardalis.Specification/Evaluators/ISpecificationEvaluator.cs index 824d9f50..c4f08861 100644 --- a/Specification/src/Ardalis.Specification/Evaluators/ISpecificationEvaluator.cs +++ b/Specification/src/Ardalis.Specification/Evaluators/ISpecificationEvaluator.cs @@ -1,30 +1,26 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; +using System.Linq; -namespace Ardalis.Specification +namespace Ardalis.Specification; + +/// +/// Evaluates the logic encapsulated by an . +/// +public interface ISpecificationEvaluator { /// - /// Evaluates the logic encapsulated by an . + /// Applies the logic encapsulated by to given , + /// and projects the result into . + /// + /// The type of the result. + /// The sequence of + /// The encapsulated query logic. + /// A filtered sequence of + IQueryable GetQuery(IQueryable inputQuery, ISpecification specification) where T : class; + /// + /// Applies the logic encapsulated by to given . /// - public interface ISpecificationEvaluator - { - /// - /// Applies the logic encapsulated by to given , - /// and projects the result into . - /// - /// The type of the result. - /// The sequence of - /// The encapsulated query logic. - /// A filtered sequence of - IQueryable GetQuery(IQueryable inputQuery, ISpecification specification) where T : class; - /// - /// Applies the logic encapsulated by to given . - /// - /// The sequence of - /// The encapsulated query logic. - /// A filtered sequence of - IQueryable GetQuery(IQueryable inputQuery, ISpecification specification, bool evaluateCriteriaOnly = false) where T : class; - } + /// The sequence of + /// The encapsulated query logic. + /// A filtered sequence of + IQueryable GetQuery(IQueryable inputQuery, ISpecification specification, bool evaluateCriteriaOnly = false) where T : class; } diff --git a/Specification/src/Ardalis.Specification/Evaluators/InMemorySpecificationEvaluator.cs b/Specification/src/Ardalis.Specification/Evaluators/InMemorySpecificationEvaluator.cs index 26df3d5f..fc893a68 100644 --- a/Specification/src/Ardalis.Specification/Evaluators/InMemorySpecificationEvaluator.cs +++ b/Specification/src/Ardalis.Specification/Evaluators/InMemorySpecificationEvaluator.cs @@ -1,60 +1,55 @@ -using System; -using System.Collections; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; -using System.Linq.Expressions; -using System.Text; -namespace Ardalis.Specification +namespace Ardalis.Specification; + +public class InMemorySpecificationEvaluator : IInMemorySpecificationEvaluator { - public class InMemorySpecificationEvaluator : IInMemorySpecificationEvaluator - { - // Will use singleton for default configuration. Yet, it can be instantiated if necessary, with default or provided evaluators. - public static InMemorySpecificationEvaluator Default { get; } = new InMemorySpecificationEvaluator(); + // Will use singleton for default configuration. Yet, it can be instantiated if necessary, with default or provided evaluators. + public static InMemorySpecificationEvaluator Default { get; } = new InMemorySpecificationEvaluator(); - protected List Evaluators { get; } = new List(); + protected List Evaluators { get; } = new List(); - public InMemorySpecificationEvaluator() - { - this.Evaluators.AddRange(new IInMemoryEvaluator[] - { - WhereEvaluator.Instance, - SearchEvaluator.Instance, - OrderEvaluator.Instance, - PaginationEvaluator.Instance - }); - } - public InMemorySpecificationEvaluator(IEnumerable evaluators) + public InMemorySpecificationEvaluator() + { + Evaluators.AddRange(new IInMemoryEvaluator[] { - this.Evaluators.AddRange(evaluators); - } + WhereEvaluator.Instance, + SearchEvaluator.Instance, + OrderEvaluator.Instance, + PaginationEvaluator.Instance + }); + } + public InMemorySpecificationEvaluator(IEnumerable evaluators) + { + Evaluators.AddRange(evaluators); + } - public virtual IEnumerable Evaluate(IEnumerable source, ISpecification specification) - { - if (specification.Selector is null && specification.SelectorMany is null) throw new SelectorNotFoundException(); - if (specification.Selector != null && specification.SelectorMany != null) throw new ConcurrentSelectorsException(); + public virtual IEnumerable Evaluate(IEnumerable source, ISpecification specification) + { + if (specification.Selector is null && specification.SelectorMany is null) throw new SelectorNotFoundException(); + if (specification.Selector != null && specification.SelectorMany != null) throw new ConcurrentSelectorsException(); - var baseQuery = Evaluate(source, (ISpecification)specification); + var baseQuery = Evaluate(source, (ISpecification)specification); - var resultQuery = specification.Selector != null - ? baseQuery.Select(specification.Selector.Compile()) - : baseQuery.SelectMany(specification.SelectorMany!.Compile()); + var resultQuery = specification.Selector != null + ? baseQuery.Select(specification.Selector.Compile()) + : baseQuery.SelectMany(specification.SelectorMany!.Compile()); - return specification.PostProcessingAction == null - ? resultQuery - : specification.PostProcessingAction(resultQuery); - } + return specification.PostProcessingAction == null + ? resultQuery + : specification.PostProcessingAction(resultQuery); + } - public virtual IEnumerable Evaluate(IEnumerable source, ISpecification specification) + public virtual IEnumerable Evaluate(IEnumerable source, ISpecification specification) + { + foreach (var evaluator in Evaluators) { - foreach (var evaluator in Evaluators) - { - source = evaluator.Evaluate(source, specification); - } - - return specification.PostProcessingAction == null - ? source - : specification.PostProcessingAction(source); + source = evaluator.Evaluate(source, specification); } + + return specification.PostProcessingAction == null + ? source + : specification.PostProcessingAction(source); } } diff --git a/Specification/src/Ardalis.Specification/Evaluators/OrderEvaluator.cs b/Specification/src/Ardalis.Specification/Evaluators/OrderEvaluator.cs index da8e4862..1d426d3f 100644 --- a/Specification/src/Ardalis.Specification/Evaluators/OrderEvaluator.cs +++ b/Specification/src/Ardalis.Specification/Evaluators/OrderEvaluator.cs @@ -1,93 +1,92 @@ using System.Collections.Generic; using System.Linq; -namespace Ardalis.Specification +namespace Ardalis.Specification; + +public class OrderEvaluator : IEvaluator, IInMemoryEvaluator { - public class OrderEvaluator : IEvaluator, IInMemoryEvaluator - { - private OrderEvaluator() { } - public static OrderEvaluator Instance { get; } = new OrderEvaluator(); + private OrderEvaluator() { } + public static OrderEvaluator Instance { get; } = new OrderEvaluator(); - public bool IsCriteriaEvaluator { get; } = false; + public bool IsCriteriaEvaluator { get; } = false; - public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class + public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class + { + if (specification.OrderExpressions != null) { - if (specification.OrderExpressions != null) + if (specification.OrderExpressions.Count(x => x.OrderType == OrderTypeEnum.OrderBy + || x.OrderType == OrderTypeEnum.OrderByDescending) > 1) { - if (specification.OrderExpressions.Count(x => x.OrderType == OrderTypeEnum.OrderBy - || x.OrderType == OrderTypeEnum.OrderByDescending) > 1) + throw new DuplicateOrderChainException(); + } + + IOrderedQueryable? orderedQuery = null; + foreach (var orderExpression in specification.OrderExpressions) + { + if (orderExpression.OrderType == OrderTypeEnum.OrderBy) { - throw new DuplicateOrderChainException(); + orderedQuery = query.OrderBy(orderExpression.KeySelector); } - - IOrderedQueryable? orderedQuery = null; - foreach (var orderExpression in specification.OrderExpressions) + else if (orderExpression.OrderType == OrderTypeEnum.OrderByDescending) { - if (orderExpression.OrderType == OrderTypeEnum.OrderBy) - { - orderedQuery = query.OrderBy(orderExpression.KeySelector); - } - else if (orderExpression.OrderType == OrderTypeEnum.OrderByDescending) - { - orderedQuery = query.OrderByDescending(orderExpression.KeySelector); - } - else if (orderExpression.OrderType == OrderTypeEnum.ThenBy) - { - orderedQuery = orderedQuery.ThenBy(orderExpression.KeySelector); - } - else if (orderExpression.OrderType == OrderTypeEnum.ThenByDescending) - { - orderedQuery = orderedQuery.ThenByDescending(orderExpression.KeySelector); - } + orderedQuery = query.OrderByDescending(orderExpression.KeySelector); } - - if (orderedQuery != null) + else if (orderExpression.OrderType == OrderTypeEnum.ThenBy) + { + orderedQuery = orderedQuery!.ThenBy(orderExpression.KeySelector); + } + else if (orderExpression.OrderType == OrderTypeEnum.ThenByDescending) { - query = orderedQuery; + orderedQuery = orderedQuery!.ThenByDescending(orderExpression.KeySelector); } } - return query; + if (orderedQuery != null) + { + query = orderedQuery; + } } - public IEnumerable Evaluate(IEnumerable query, ISpecification specification) + return query; + } + + public IEnumerable Evaluate(IEnumerable query, ISpecification specification) + { + if (specification.OrderExpressions != null) { - if (specification.OrderExpressions != null) + if (specification.OrderExpressions.Count(x => x.OrderType == OrderTypeEnum.OrderBy + || x.OrderType == OrderTypeEnum.OrderByDescending) > 1) + { + throw new DuplicateOrderChainException(); + } + + IOrderedEnumerable? orderedQuery = null; + foreach (var orderExpression in specification.OrderExpressions) { - if (specification.OrderExpressions.Count(x => x.OrderType == OrderTypeEnum.OrderBy - || x.OrderType == OrderTypeEnum.OrderByDescending) > 1) + if (orderExpression.OrderType == OrderTypeEnum.OrderBy) { - throw new DuplicateOrderChainException(); + orderedQuery = query.OrderBy(orderExpression.KeySelectorFunc); } - - IOrderedEnumerable? orderedQuery = null; - foreach (var orderExpression in specification.OrderExpressions) + else if (orderExpression.OrderType == OrderTypeEnum.OrderByDescending) { - if (orderExpression.OrderType == OrderTypeEnum.OrderBy) - { - orderedQuery = query.OrderBy(orderExpression.KeySelectorFunc); - } - else if (orderExpression.OrderType == OrderTypeEnum.OrderByDescending) - { - orderedQuery = query.OrderByDescending(orderExpression.KeySelectorFunc); - } - else if (orderExpression.OrderType == OrderTypeEnum.ThenBy) - { - orderedQuery = orderedQuery.ThenBy(orderExpression.KeySelectorFunc); - } - else if (orderExpression.OrderType == OrderTypeEnum.ThenByDescending) - { - orderedQuery = orderedQuery.ThenByDescending(orderExpression.KeySelectorFunc); - } + orderedQuery = query.OrderByDescending(orderExpression.KeySelectorFunc); } - - if (orderedQuery != null) + else if (orderExpression.OrderType == OrderTypeEnum.ThenBy) + { + orderedQuery = orderedQuery!.ThenBy(orderExpression.KeySelectorFunc); + } + else if (orderExpression.OrderType == OrderTypeEnum.ThenByDescending) { - query = orderedQuery; + orderedQuery = orderedQuery!.ThenByDescending(orderExpression.KeySelectorFunc); } } - return query; + if (orderedQuery != null) + { + query = orderedQuery; + } } + + return query; } } diff --git a/Specification/src/Ardalis.Specification/Evaluators/PaginationEvaluator.cs b/Specification/src/Ardalis.Specification/Evaluators/PaginationEvaluator.cs index 41173a74..397207e9 100644 --- a/Specification/src/Ardalis.Specification/Evaluators/PaginationEvaluator.cs +++ b/Specification/src/Ardalis.Specification/Evaluators/PaginationEvaluator.cs @@ -1,46 +1,43 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; -using System.Text; -namespace Ardalis.Specification +namespace Ardalis.Specification; + +public class PaginationEvaluator : IEvaluator, IInMemoryEvaluator { - public class PaginationEvaluator : IEvaluator, IInMemoryEvaluator - { - private PaginationEvaluator() { } - public static PaginationEvaluator Instance { get; } = new PaginationEvaluator(); + private PaginationEvaluator() { } + public static PaginationEvaluator Instance { get; } = new PaginationEvaluator(); - public bool IsCriteriaEvaluator { get; } = false; + public bool IsCriteriaEvaluator { get; } = false; - public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class + public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class + { + // If skip is 0, avoid adding to the IQueryable. It will generate more optimized SQL that way. + if (specification.Skip != null && specification.Skip != 0) { - // If skip is 0, avoid adding to the IQueryable. It will generate more optimized SQL that way. - if (specification.Skip != null && specification.Skip != 0) - { - query = query.Skip(specification.Skip.Value); - } - - if (specification.Take != null) - { - query = query.Take(specification.Take.Value); - } - - return query; + query = query.Skip(specification.Skip.Value); } - public IEnumerable Evaluate(IEnumerable query, ISpecification specification) + if (specification.Take != null) { - if (specification.Skip != null && specification.Skip != 0) - { - query = query.Skip(specification.Skip.Value); - } + query = query.Take(specification.Take.Value); + } - if (specification.Take != null) - { - query = query.Take(specification.Take.Value); - } + return query; + } - return query; + public IEnumerable Evaluate(IEnumerable query, ISpecification specification) + { + if (specification.Skip != null && specification.Skip != 0) + { + query = query.Skip(specification.Skip.Value); } + + if (specification.Take != null) + { + query = query.Take(specification.Take.Value); + } + + return query; } } diff --git a/Specification/src/Ardalis.Specification/Evaluators/SearchEvaluator.cs b/Specification/src/Ardalis.Specification/Evaluators/SearchEvaluator.cs index c84ac0b0..ece22642 100644 --- a/Specification/src/Ardalis.Specification/Evaluators/SearchEvaluator.cs +++ b/Specification/src/Ardalis.Specification/Evaluators/SearchEvaluator.cs @@ -1,21 +1,20 @@ using System.Collections.Generic; using System.Linq; -namespace Ardalis.Specification +namespace Ardalis.Specification; + +public class SearchEvaluator : IInMemoryEvaluator { - public class SearchEvaluator : IInMemoryEvaluator - { - private SearchEvaluator() { } - public static SearchEvaluator Instance { get; } = new SearchEvaluator(); + private SearchEvaluator() { } + public static SearchEvaluator Instance { get; } = new SearchEvaluator(); - public IEnumerable Evaluate(IEnumerable query, ISpecification specification) + public IEnumerable Evaluate(IEnumerable query, ISpecification specification) + { + foreach (var searchGroup in specification.SearchCriterias.GroupBy(x => x.SearchGroup)) { - foreach (var searchGroup in specification.SearchCriterias.GroupBy(x => x.SearchGroup)) - { - query = query.Where(x => searchGroup.Any(c => c.SelectorFunc(x).Like(c.SearchTerm))); - } - - return query; + query = query.Where(x => searchGroup.Any(c => c.SelectorFunc(x).Like(c.SearchTerm))); } + + return query; } } diff --git a/Specification/src/Ardalis.Specification/Evaluators/SearchExtension.cs b/Specification/src/Ardalis.Specification/Evaluators/SearchExtension.cs index 5981dfed..09706ecf 100644 --- a/Specification/src/Ardalis.Specification/Evaluators/SearchExtension.cs +++ b/Specification/src/Ardalis.Specification/Evaluators/SearchExtension.cs @@ -1,158 +1,155 @@ using System; using System.Collections.Generic; -using System.Text; -namespace Ardalis.Specification +namespace Ardalis.Specification; + +public static class SearchExtension { - public static class SearchExtension + public static bool Like(this string input, string pattern) { - public static bool Like(this string input, string pattern) + try { - try - { - return SqlLike(input, pattern); - } - catch (Exception) - { - throw new InvalidSearchPatternException(pattern); - } + return SqlLike(input, pattern); } - - // This C# implementation of SQL Like operator is based on the following SO post https://stackoverflow.com/a/8583383/10577116 - // It covers almost all of the scenarios, and it's faster than regex based implementations. - // It may fail/throw in some very specific and edge cases, hence, wrap it in try/catch. - private static bool SqlLike(string str, string pattern) + catch (Exception) { - bool isMatch = true, - isWildCardOn = false, - isCharWildCardOn = false, - isCharSetOn = false, - isNotCharSetOn = false, - endOfPattern = false; - int lastWildCard = -1; - int patternIndex = 0; - List set = new List(); - char p = '\0'; + throw new InvalidSearchPatternException(pattern); + } + } - for (int i = 0; i < str.Length; i++) + // This C# implementation of SQL Like operator is based on the following SO post https://stackoverflow.com/a/8583383/10577116 + // It covers almost all of the scenarios, and it's faster than regex based implementations. + // It may fail/throw in some very specific and edge cases, hence, wrap it in try/catch. + private static bool SqlLike(string str, string pattern) + { + var isMatch = true; + var isWildCardOn = false; + var isCharWildCardOn = false; + var isCharSetOn = false; + var isNotCharSetOn = false; + var lastWildCard = -1; + var patternIndex = 0; + var set = new List(); + var p = '\0'; + bool endOfPattern; + + for (var i = 0; i < str.Length; i++) + { + var c = str[i]; + endOfPattern = (patternIndex >= pattern.Length); + if (!endOfPattern) { - char c = str[i]; - endOfPattern = (patternIndex >= pattern.Length); - if (!endOfPattern) - { - p = pattern[patternIndex]; + p = pattern[patternIndex]; - if (!isWildCardOn && p == '%') + if (!isWildCardOn && p == '%') + { + lastWildCard = patternIndex; + isWildCardOn = true; + while (patternIndex < pattern.Length && + pattern[patternIndex] == '%') { - lastWildCard = patternIndex; - isWildCardOn = true; - while (patternIndex < pattern.Length && - pattern[patternIndex] == '%') - { - patternIndex++; - } - if (patternIndex >= pattern.Length) p = '\0'; - else p = pattern[patternIndex]; + patternIndex++; } - else if (p == '_') + p = patternIndex >= pattern.Length ? '\0' : pattern[patternIndex]; + } + else if (p == '_') + { + isCharWildCardOn = true; + patternIndex++; + } + else if (p == '[') + { + if (pattern[++patternIndex] == '^') { - isCharWildCardOn = true; + isNotCharSetOn = true; patternIndex++; } - else if (p == '[') - { - if (pattern[++patternIndex] == '^') - { - isNotCharSetOn = true; - patternIndex++; - } - else isCharSetOn = true; + else isCharSetOn = true; - set.Clear(); - if (pattern[patternIndex + 1] == '-' && pattern[patternIndex + 3] == ']') + set.Clear(); + if (pattern[patternIndex + 1] == '-' && pattern[patternIndex + 3] == ']') + { + var start = char.ToUpper(pattern[patternIndex]); + patternIndex += 2; + var end = char.ToUpper(pattern[patternIndex]); + if (start <= end) { - char start = char.ToUpper(pattern[patternIndex]); - patternIndex += 2; - char end = char.ToUpper(pattern[patternIndex]); - if (start <= end) + for (var ci = start; ci <= end; ci++) { - for (char ci = start; ci <= end; ci++) - { - set.Add(ci); - } + set.Add(ci); } - patternIndex++; - } - - while (patternIndex < pattern.Length && - pattern[patternIndex] != ']') - { - set.Add(pattern[patternIndex]); - patternIndex++; } patternIndex++; } - } - if (isWildCardOn) - { - if (char.ToUpper(c) == char.ToUpper(p)) + while (patternIndex < pattern.Length && + pattern[patternIndex] != ']') { - isWildCardOn = false; + set.Add(pattern[patternIndex]); patternIndex++; } + patternIndex++; } - else if (isCharWildCardOn) + } + + if (isWildCardOn) + { + if (char.ToUpper(c) == char.ToUpper(p)) { - isCharWildCardOn = false; + isWildCardOn = false; + patternIndex++; } - else if (isCharSetOn || isNotCharSetOn) + } + else if (isCharWildCardOn) + { + isCharWildCardOn = false; + } + else if (isCharSetOn || isNotCharSetOn) + { + var charMatch = (set.Contains(char.ToUpper(c))); + if ((isNotCharSetOn && charMatch) || (isCharSetOn && !charMatch)) { - bool charMatch = (set.Contains(char.ToUpper(c))); - if ((isNotCharSetOn && charMatch) || (isCharSetOn && !charMatch)) + if (lastWildCard >= 0) patternIndex = lastWildCard; + else { - if (lastWildCard >= 0) patternIndex = lastWildCard; - else - { - isMatch = false; - break; - } + isMatch = false; + break; } - isNotCharSetOn = isCharSetOn = false; + } + isNotCharSetOn = isCharSetOn = false; + } + else + { + if (char.ToUpper(c) == char.ToUpper(p)) + { + patternIndex++; } else { - if (char.ToUpper(c) == char.ToUpper(p)) - { - patternIndex++; - } + if (lastWildCard >= 0) patternIndex = lastWildCard; else { - if (lastWildCard >= 0) patternIndex = lastWildCard; - else - { - isMatch = false; - break; - } + isMatch = false; + break; } } } - endOfPattern = (patternIndex >= pattern.Length); + } + endOfPattern = (patternIndex >= pattern.Length); - if (isMatch && !endOfPattern) + if (isMatch && !endOfPattern) + { + var isOnlyWildCards = true; + for (var i = patternIndex; i < pattern.Length; i++) { - bool isOnlyWildCards = true; - for (int i = patternIndex; i < pattern.Length; i++) + if (pattern[i] != '%') { - if (pattern[i] != '%') - { - isOnlyWildCards = false; - break; - } + isOnlyWildCards = false; + break; } - if (isOnlyWildCards) endOfPattern = true; } - return isMatch && endOfPattern; + if (isOnlyWildCards) endOfPattern = true; } + return isMatch && endOfPattern; } } diff --git a/Specification/src/Ardalis.Specification/Evaluators/WhereEvaluator.cs b/Specification/src/Ardalis.Specification/Evaluators/WhereEvaluator.cs index 135fa261..33d1907a 100644 --- a/Specification/src/Ardalis.Specification/Evaluators/WhereEvaluator.cs +++ b/Specification/src/Ardalis.Specification/Evaluators/WhereEvaluator.cs @@ -1,33 +1,32 @@ using System.Collections.Generic; using System.Linq; -namespace Ardalis.Specification +namespace Ardalis.Specification; + +public class WhereEvaluator : IEvaluator, IInMemoryEvaluator { - public class WhereEvaluator : IEvaluator, IInMemoryEvaluator - { - private WhereEvaluator() { } - public static WhereEvaluator Instance { get; } = new WhereEvaluator(); + private WhereEvaluator() { } + public static WhereEvaluator Instance { get; } = new WhereEvaluator(); - public bool IsCriteriaEvaluator { get; } = true; + public bool IsCriteriaEvaluator { get; } = true; - public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class + public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class + { + foreach (var info in specification.WhereExpressions) { - foreach (var info in specification.WhereExpressions) - { - query = query.Where(info.Filter); - } - - return query; + query = query.Where(info.Filter); } - public IEnumerable Evaluate(IEnumerable query, ISpecification specification) - { - foreach (var info in specification.WhereExpressions) - { - query = query.Where(info.FilterFunc); - } + return query; + } - return query; + public IEnumerable Evaluate(IEnumerable query, ISpecification specification) + { + foreach (var info in specification.WhereExpressions) + { + query = query.Where(info.FilterFunc); } + + return query; } } diff --git a/Specification/src/Ardalis.Specification/Exceptions/ConcurrentSelectorsException.cs b/Specification/src/Ardalis.Specification/Exceptions/ConcurrentSelectorsException.cs index a145c7aa..e6d3a134 100644 --- a/Specification/src/Ardalis.Specification/Exceptions/ConcurrentSelectorsException.cs +++ b/Specification/src/Ardalis.Specification/Exceptions/ConcurrentSelectorsException.cs @@ -1,19 +1,18 @@ using System; -namespace Ardalis.Specification +namespace Ardalis.Specification; + +public class ConcurrentSelectorsException : Exception { - public class ConcurrentSelectorsException : Exception - { - private const string message = "Concurrent specification selector transforms defined. Ensure only one of the Select() or SelectMany() transforms is used in the same specification!"; + private const string _message = "Concurrent specification selector transforms defined. Ensure only one of the Select() or SelectMany() transforms is used in the same specification!"; - public ConcurrentSelectorsException() - : base(message) - { - } + public ConcurrentSelectorsException() + : base(_message) + { + } - public ConcurrentSelectorsException(Exception innerException) - : base(message, innerException) - { - } + public ConcurrentSelectorsException(Exception innerException) + : base(_message, innerException) + { } } diff --git a/Specification/src/Ardalis.Specification/Exceptions/DuplicateOrderChainException.cs b/Specification/src/Ardalis.Specification/Exceptions/DuplicateOrderChainException.cs index 1ecaf6f1..e9887d12 100644 --- a/Specification/src/Ardalis.Specification/Exceptions/DuplicateOrderChainException.cs +++ b/Specification/src/Ardalis.Specification/Exceptions/DuplicateOrderChainException.cs @@ -1,22 +1,18 @@ using System; -using System.Collections.Generic; -using System.Data; -using System.Text; -namespace Ardalis.Specification +namespace Ardalis.Specification; + +public class DuplicateOrderChainException : Exception { - public class DuplicateOrderChainException : Exception - { - private const string message = "The specification contains more than one Order chain!"; + private const string _message = "The specification contains more than one Order chain!"; - public DuplicateOrderChainException() - : base(message) - { - } + public DuplicateOrderChainException() + : base(_message) + { + } - public DuplicateOrderChainException(Exception innerException) - : base(message, innerException) - { - } + public DuplicateOrderChainException(Exception innerException) + : base(_message, innerException) + { } } diff --git a/Specification/src/Ardalis.Specification/Exceptions/DuplicateSkipException.cs b/Specification/src/Ardalis.Specification/Exceptions/DuplicateSkipException.cs index e83edcd5..082f9d31 100644 --- a/Specification/src/Ardalis.Specification/Exceptions/DuplicateSkipException.cs +++ b/Specification/src/Ardalis.Specification/Exceptions/DuplicateSkipException.cs @@ -1,21 +1,18 @@ using System; -using System.Collections.Generic; -using System.Text; -namespace Ardalis.Specification +namespace Ardalis.Specification; + +public class DuplicateSkipException : Exception { - public class DuplicateSkipException : Exception - { - private const string message = "Duplicate use of Skip(). Ensure you don't use Skip() more than once in the same specification!"; + private const string _message = "Duplicate use of Skip(). Ensure you don't use Skip() more than once in the same specification!"; - public DuplicateSkipException() - : base(message) - { - } + public DuplicateSkipException() + : base(_message) + { + } - public DuplicateSkipException(Exception innerException) - : base(message, innerException) - { - } + public DuplicateSkipException(Exception innerException) + : base(_message, innerException) + { } } diff --git a/Specification/src/Ardalis.Specification/Exceptions/DuplicateTakeException.cs b/Specification/src/Ardalis.Specification/Exceptions/DuplicateTakeException.cs index 7a1cc2c5..6c1ec900 100644 --- a/Specification/src/Ardalis.Specification/Exceptions/DuplicateTakeException.cs +++ b/Specification/src/Ardalis.Specification/Exceptions/DuplicateTakeException.cs @@ -1,21 +1,18 @@ using System; -using System.Collections.Generic; -using System.Text; -namespace Ardalis.Specification +namespace Ardalis.Specification; + +public class DuplicateTakeException : Exception { - public class DuplicateTakeException : Exception - { - private const string message = "Duplicate use of Take(). Ensure you don't use Take() more than once in the same specification!"; + private const string _message = "Duplicate use of Take(). Ensure you don't use Take() more than once in the same specification!"; - public DuplicateTakeException() - : base(message) - { - } + public DuplicateTakeException() + : base(_message) + { + } - public DuplicateTakeException(Exception innerException) - : base(message, innerException) - { - } + public DuplicateTakeException(Exception innerException) + : base(_message, innerException) + { } } diff --git a/Specification/src/Ardalis.Specification/Exceptions/InvalidSearchPatternException.cs b/Specification/src/Ardalis.Specification/Exceptions/InvalidSearchPatternException.cs index 21e685d5..3a047898 100644 --- a/Specification/src/Ardalis.Specification/Exceptions/InvalidSearchPatternException.cs +++ b/Specification/src/Ardalis.Specification/Exceptions/InvalidSearchPatternException.cs @@ -1,21 +1,18 @@ using System; -using System.Collections.Generic; -using System.Text; -namespace Ardalis.Specification +namespace Ardalis.Specification; + +public class InvalidSearchPatternException : Exception { - public class InvalidSearchPatternException : Exception - { - private const string message = "Invalid search pattern: "; + private const string _message = "Invalid search pattern: "; - public InvalidSearchPatternException(string searchPattern) - : base($"{message}{searchPattern}") - { - } + public InvalidSearchPatternException(string searchPattern) + : base($"{_message}{searchPattern}") + { + } - public InvalidSearchPatternException(string searchPattern, Exception innerException) - : base($"{message}{searchPattern}", innerException) - { - } + public InvalidSearchPatternException(string searchPattern, Exception innerException) + : base($"{_message}{searchPattern}", innerException) + { } } diff --git a/Specification/src/Ardalis.Specification/Exceptions/SelectorNotFoundException.cs b/Specification/src/Ardalis.Specification/Exceptions/SelectorNotFoundException.cs index e8baf32e..b011a239 100644 --- a/Specification/src/Ardalis.Specification/Exceptions/SelectorNotFoundException.cs +++ b/Specification/src/Ardalis.Specification/Exceptions/SelectorNotFoundException.cs @@ -1,19 +1,18 @@ using System; -namespace Ardalis.Specification +namespace Ardalis.Specification; + +public class SelectorNotFoundException : Exception { - public class SelectorNotFoundException : Exception - { - private const string message = "The specification must have a selector transform defined. Ensure either Select() or SelectMany() is used in the specification!"; + private const string _message = "The specification must have a selector transform defined. Ensure either Select() or SelectMany() is used in the specification!"; - public SelectorNotFoundException() - : base(message) - { - } + public SelectorNotFoundException() + : base(_message) + { + } - public SelectorNotFoundException(Exception innerException) - : base(message, innerException) - { - } + public SelectorNotFoundException(Exception innerException) + : base(_message, innerException) + { } } diff --git a/Specification/src/Ardalis.Specification/Expressions/IncludeExpressionInfo.cs b/Specification/src/Ardalis.Specification/Expressions/IncludeExpressionInfo.cs index 2967c88c..8e4097ee 100644 --- a/Specification/src/Ardalis.Specification/Expressions/IncludeExpressionInfo.cs +++ b/Specification/src/Ardalis.Specification/Expressions/IncludeExpressionInfo.cs @@ -1,90 +1,89 @@ using System; using System.Linq.Expressions; -namespace Ardalis.Specification +namespace Ardalis.Specification; + +/// +/// Encapsulates data needed to build Include/ThenInclude query. +/// +public class IncludeExpressionInfo { /// - /// Encapsulates data needed to build Include/ThenInclude query. + /// If is , represents a related entity that should be included. + /// If is , represents a related entity that should be included as part of the previously included entity. /// - public class IncludeExpressionInfo - { - /// - /// If is , represents a related entity that should be included. - /// If is , represents a related entity that should be included as part of the previously included entity. - /// - public LambdaExpression LambdaExpression { get; } - - /// - /// The type of the source entity. - /// - public Type EntityType { get; } - - /// - /// The type of the included entity. - /// - public Type PropertyType { get; } + public LambdaExpression LambdaExpression { get; } - /// - /// The type of the previously included entity. - /// - public Type? PreviousPropertyType { get; } + /// + /// The type of the source entity. + /// + public Type EntityType { get; } - /// - /// The include type. - /// - public IncludeTypeEnum Type { get; } + /// + /// The type of the included entity. + /// + public Type PropertyType { get; } - private IncludeExpressionInfo(LambdaExpression expression, - Type entityType, - Type propertyType, - Type? previousPropertyType, - IncludeTypeEnum includeType) + /// + /// The type of the previously included entity. + /// + public Type? PreviousPropertyType { get; } - { - _ = expression ?? throw new ArgumentNullException(nameof(expression)); - _ = entityType ?? throw new ArgumentNullException(nameof(entityType)); - _ = propertyType ?? throw new ArgumentNullException(nameof(propertyType)); + /// + /// The include type. + /// + public IncludeTypeEnum Type { get; } - if (includeType == IncludeTypeEnum.ThenInclude) - { - _ = previousPropertyType ?? throw new ArgumentNullException(nameof(previousPropertyType)); - } + private IncludeExpressionInfo(LambdaExpression expression, + Type entityType, + Type propertyType, + Type? previousPropertyType, + IncludeTypeEnum includeType) - this.LambdaExpression = expression; - this.EntityType = entityType; - this.PropertyType = propertyType; - this.PreviousPropertyType = previousPropertyType; - this.Type = includeType; - } + { + _ = expression ?? throw new ArgumentNullException(nameof(expression)); + _ = entityType ?? throw new ArgumentNullException(nameof(entityType)); + _ = propertyType ?? throw new ArgumentNullException(nameof(propertyType)); - /// - /// Creates instance of which describes 'Include' query part. - /// Source (entityType) -> Include (propertyType). - /// - /// The expression represents a related entity that should be included. - /// The type of the source entity. - /// The type of the included entity. - public IncludeExpressionInfo(LambdaExpression expression, - Type entityType, - Type propertyType) - : this(expression, entityType, propertyType, null, IncludeTypeEnum.Include) + if (includeType == IncludeTypeEnum.ThenInclude) { + _ = previousPropertyType ?? throw new ArgumentNullException(nameof(previousPropertyType)); } - /// - /// Creates instance of which describes 'ThenInclude' query part. - /// Source (entityType) -> Include (previousPropertyType) -> ThenInclude (propertyType). - /// - /// The expression represents a related entity that should be included as part of the previously included entity. - /// The type of the source entity. - /// The type of the included entity. - /// The type of the previously included entity. - public IncludeExpressionInfo(LambdaExpression expression, - Type entityType, - Type propertyType, - Type previousPropertyType) - : this(expression, entityType, propertyType, previousPropertyType, IncludeTypeEnum.ThenInclude) - { - } + LambdaExpression = expression; + EntityType = entityType; + PropertyType = propertyType; + PreviousPropertyType = previousPropertyType; + Type = includeType; + } + + /// + /// Creates instance of which describes 'Include' query part. + /// Source (entityType) -> Include (propertyType). + /// + /// The expression represents a related entity that should be included. + /// The type of the source entity. + /// The type of the included entity. + public IncludeExpressionInfo(LambdaExpression expression, + Type entityType, + Type propertyType) + : this(expression, entityType, propertyType, null, IncludeTypeEnum.Include) + { + } + + /// + /// Creates instance of which describes 'ThenInclude' query part. + /// Source (entityType) -> Include (previousPropertyType) -> ThenInclude (propertyType). + /// + /// The expression represents a related entity that should be included as part of the previously included entity. + /// The type of the source entity. + /// The type of the included entity. + /// The type of the previously included entity. + public IncludeExpressionInfo(LambdaExpression expression, + Type entityType, + Type propertyType, + Type previousPropertyType) + : this(expression, entityType, propertyType, previousPropertyType, IncludeTypeEnum.ThenInclude) + { } } diff --git a/Specification/src/Ardalis.Specification/Expressions/OrderExpressionInfo.cs b/Specification/src/Ardalis.Specification/Expressions/OrderExpressionInfo.cs index 0140e3d9..be98070e 100644 --- a/Specification/src/Ardalis.Specification/Expressions/OrderExpressionInfo.cs +++ b/Specification/src/Ardalis.Specification/Expressions/OrderExpressionInfo.cs @@ -1,45 +1,44 @@ using System; using System.Linq.Expressions; -namespace Ardalis.Specification +namespace Ardalis.Specification; + +/// +/// Encapsulates data needed to perform sorting. +/// +/// Type of the entity to apply sort on. +public class OrderExpressionInfo { + private readonly Lazy> _keySelectorFunc; + /// - /// Encapsulates data needed to perform sorting. + /// Creates instance of . /// - /// Type of the entity to apply sort on. - public class OrderExpressionInfo + /// A function to extract a key from an element. + /// Whether to (subsequently) sort ascending or descending. + /// If is null. + public OrderExpressionInfo(Expression> keySelector, OrderTypeEnum orderType) { - private readonly Lazy> keySelectorFunc; - - /// - /// Creates instance of . - /// - /// A function to extract a key from an element. - /// Whether to (subsequently) sort ascending or descending. - /// If is null. - public OrderExpressionInfo(Expression> keySelector, OrderTypeEnum orderType) - { - _ = keySelector ?? throw new ArgumentNullException(nameof(keySelector)); - - this.KeySelector = keySelector; - this.OrderType = orderType; - - this.keySelectorFunc = new Lazy>(this.KeySelector.Compile); - } - - /// - /// A function to extract a key from an element. - /// - public Expression> KeySelector { get; } - - /// - /// Whether to (subsequently) sort ascending or descending. - /// - public OrderTypeEnum OrderType { get; } - - /// - /// Compiled . - /// - public Func KeySelectorFunc => this.keySelectorFunc.Value; + _ = keySelector ?? throw new ArgumentNullException(nameof(keySelector)); + + KeySelector = keySelector; + OrderType = orderType; + + _keySelectorFunc = new Lazy>(KeySelector.Compile); } + + /// + /// A function to extract a key from an element. + /// + public Expression> KeySelector { get; } + + /// + /// Whether to (subsequently) sort ascending or descending. + /// + public OrderTypeEnum OrderType { get; } + + /// + /// Compiled . + /// + public Func KeySelectorFunc => _keySelectorFunc.Value; } diff --git a/Specification/src/Ardalis.Specification/Expressions/SearchExpressionInfo.cs b/Specification/src/Ardalis.Specification/Expressions/SearchExpressionInfo.cs index d0774802..e785dd35 100644 --- a/Specification/src/Ardalis.Specification/Expressions/SearchExpressionInfo.cs +++ b/Specification/src/Ardalis.Specification/Expressions/SearchExpressionInfo.cs @@ -1,54 +1,53 @@ using System; using System.Linq.Expressions; -namespace Ardalis.Specification +namespace Ardalis.Specification; + +/// +/// Encapsulates data needed to perform 'SQL LIKE' operation. +/// +/// Type of the source from which search target should be selected. +public class SearchExpressionInfo { + private readonly Lazy> _selectorFunc; + /// - /// Encapsulates data needed to perform 'SQL LIKE' operation. + /// Creates instance of . /// - /// Type of the source from which search target should be selected. - public class SearchExpressionInfo + /// The property to apply the SQL LIKE against. + /// The value to use for the SQL LIKE. + /// The index used to group sets of Selectors and SearchTerms together. + /// If is null. + /// If is null or empty. + public SearchExpressionInfo(Expression> selector, string searchTerm, int searchGroup = 1) { - private readonly Lazy> selectorFunc; - - /// - /// Creates instance of . - /// - /// The property to apply the SQL LIKE against. - /// The value to use for the SQL LIKE. - /// The index used to group sets of Selectors and SearchTerms together. - /// If is null. - /// If is null or empty. - public SearchExpressionInfo(Expression> selector, string searchTerm, int searchGroup = 1) - { - _ = selector ?? throw new ArgumentNullException(nameof(selector)); - if (string.IsNullOrEmpty(searchTerm)) throw new ArgumentException(nameof(searchTerm)); - - this.Selector = selector; - this.SearchTerm = searchTerm; - this.SearchGroup = searchGroup; - - this.selectorFunc = new Lazy>(this.Selector.Compile); - } - - /// - /// The property to apply the SQL LIKE against. - /// - public Expression> Selector { get; } - - /// - /// The value to use for the SQL LIKE. - /// - public string SearchTerm { get; } - - /// - /// The index used to group sets of Selectors and SearchTerms together. - /// - public int SearchGroup { get; } - - /// - /// Compiled . - /// - public Func SelectorFunc => this.selectorFunc.Value; + _ = selector ?? throw new ArgumentNullException(nameof(selector)); + if (string.IsNullOrEmpty(searchTerm)) throw new ArgumentException("The search term can not be null or empty."); + + Selector = selector; + SearchTerm = searchTerm; + SearchGroup = searchGroup; + + _selectorFunc = new Lazy>(Selector.Compile); } + + /// + /// The property to apply the SQL LIKE against. + /// + public Expression> Selector { get; } + + /// + /// The value to use for the SQL LIKE. + /// + public string SearchTerm { get; } + + /// + /// The index used to group sets of Selectors and SearchTerms together. + /// + public int SearchGroup { get; } + + /// + /// Compiled . + /// + public Func SelectorFunc => _selectorFunc.Value; } diff --git a/Specification/src/Ardalis.Specification/Expressions/WhereExpressionInfo.cs b/Specification/src/Ardalis.Specification/Expressions/WhereExpressionInfo.cs index 68202424..2680f9a7 100644 --- a/Specification/src/Ardalis.Specification/Expressions/WhereExpressionInfo.cs +++ b/Specification/src/Ardalis.Specification/Expressions/WhereExpressionInfo.cs @@ -1,38 +1,37 @@ using System; using System.Linq.Expressions; -namespace Ardalis.Specification +namespace Ardalis.Specification; + +/// +/// Encapsulates data needed to perform filtering. +/// +/// Type of the entity to apply filter on. +public class WhereExpressionInfo { + private readonly Lazy> _filterFunc; + /// - /// Encapsulates data needed to perform filtering. + /// Creates instance of . /// - /// Type of the entity to apply filter on. - public class WhereExpressionInfo + /// Condition which should be satisfied by instances of . + /// If is null. + public WhereExpressionInfo(Expression> filter) { - private readonly Lazy> filterFunc; - - /// - /// Creates instance of . - /// - /// Condition which should be satisfied by instances of . - /// If is null. - public WhereExpressionInfo(Expression> filter) - { - _ = filter ?? throw new ArgumentNullException(nameof(filter)); + _ = filter ?? throw new ArgumentNullException(nameof(filter)); - this.Filter = filter; + Filter = filter; - this.filterFunc = new Lazy>(this.Filter.Compile); - } + _filterFunc = new Lazy>(Filter.Compile); + } - /// - /// Condition which should be satisfied by instances of . - /// - public Expression> Filter { get; } + /// + /// Condition which should be satisfied by instances of . + /// + public Expression> Filter { get; } - /// - /// Compiled . - /// - public Func FilterFunc => this.filterFunc.Value; - } + /// + /// Compiled . + /// + public Func FilterFunc => _filterFunc.Value; } diff --git a/Specification/src/Ardalis.Specification/IEntity.cs b/Specification/src/Ardalis.Specification/IEntity.cs index da137948..831b2e4b 100644 --- a/Specification/src/Ardalis.Specification/IEntity.cs +++ b/Specification/src/Ardalis.Specification/IEntity.cs @@ -1,7 +1,6 @@ -namespace Ardalis.Specification +namespace Ardalis.Specification; + +public interface IEntity { - public interface IEntity - { - TId Id { get; set; } - } + TId Id { get; set; } } diff --git a/Specification/src/Ardalis.Specification/IReadRepositoryBase.cs b/Specification/src/Ardalis.Specification/IReadRepositoryBase.cs index 5867f84d..314370bc 100644 --- a/Specification/src/Ardalis.Specification/IReadRepositoryBase.cs +++ b/Specification/src/Ardalis.Specification/IReadRepositoryBase.cs @@ -3,182 +3,181 @@ using System.Threading; using System.Threading.Tasks; -namespace Ardalis.Specification +namespace Ardalis.Specification; + +/// +/// +/// A can be used to query instances of . +/// An (or derived) is used to encapsulate the LINQ queries against the database. +/// +/// +/// The type of entity being operated on by this repository. +public interface IReadRepositoryBase where T : class { /// + /// Finds an entity with the given primary key value. + /// + /// The type of primary key. + /// The value of the primary key for the entity to be found. + /// + /// + /// A task that represents the asynchronous operation. + /// The task result contains the , or . + /// + Task GetByIdAsync(TId id, CancellationToken cancellationToken = default) where TId : notnull; + + /// + /// Finds an entity that matches the encapsulated query logic of the . + /// + /// The encapsulated query logic. + /// + /// A task that represents the asynchronous operation. + /// The task result contains the , or . + /// + [Obsolete] + Task GetBySpecAsync(ISpecification specification, CancellationToken cancellationToken = default); + + /// + /// Finds an entity that matches the encapsulated query logic of the . + /// + /// The type of the result. + /// The encapsulated query logic. + /// + /// A task that represents the asynchronous operation. + /// The task result contains the . + /// + [Obsolete] + Task GetBySpecAsync(ISpecification specification, CancellationToken cancellationToken = default); + + /// + /// Returns the first element of a sequence, or a default value if the sequence contains no elements. + /// + /// The encapsulated query logic. + /// A to observe while waiting for the task to complete. + /// + /// A task that represents the asynchronous operation. + /// The task result contains the , or . + /// + Task FirstOrDefaultAsync(ISpecification specification, CancellationToken cancellationToken = default); + + /// + /// Returns the first element of a sequence, or a default value if the sequence contains no elements. + /// + /// The encapsulated query logic. + /// A to observe while waiting for the task to complete. + /// + /// A task that represents the asynchronous operation. + /// The task result contains the , or . + /// + Task FirstOrDefaultAsync(ISpecification specification, CancellationToken cancellationToken = default); + + /// + /// Returns the only element of a sequence, or a default value if the sequence is empty; this method throws an exception if there is more than one element in the sequence. + /// + /// The encapsulated query logic. + /// A to observe while waiting for the task to complete. + /// + /// A task that represents the asynchronous operation. + /// The task result contains the , or . + /// + Task SingleOrDefaultAsync(ISingleResultSpecification specification, CancellationToken cancellationToken = default); + + /// + /// Returns the only element of a sequence, or a default value if the sequence is empty; this method throws an exception if there is more than one element in the sequence. + /// + /// The encapsulated query logic. + /// A to observe while waiting for the task to complete. + /// + /// A task that represents the asynchronous operation. + /// The task result contains the , or . + /// + Task SingleOrDefaultAsync(ISingleResultSpecification specification, CancellationToken cancellationToken = default); + + /// + /// Finds all entities of from the database. + /// + /// + /// A task that represents the asynchronous operation. + /// The task result contains a that contains elements from the input sequence. + /// + Task> ListAsync(CancellationToken cancellationToken = default); + + /// + /// Finds all entities of , that matches the encapsulated query logic of the + /// , from the database. + /// + /// The encapsulated query logic. + /// + /// A task that represents the asynchronous operation. + /// The task result contains a that contains elements from the input sequence. + /// + Task> ListAsync(ISpecification specification, CancellationToken cancellationToken = default); + + /// + /// Finds all entities of , that matches the encapsulated query logic of the + /// , from the database. /// - /// A can be used to query instances of . - /// An (or derived) is used to encapsulate the LINQ queries against the database. + /// Projects each entity into a new form, being . /// /// - /// The type of entity being operated on by this repository. - public interface IReadRepositoryBase where T : class - { - /// - /// Finds an entity with the given primary key value. - /// - /// The type of primary key. - /// The value of the primary key for the entity to be found. - /// - /// - /// A task that represents the asynchronous operation. - /// The task result contains the , or . - /// - Task GetByIdAsync(TId id, CancellationToken cancellationToken = default) where TId : notnull; - - /// - /// Finds an entity that matches the encapsulated query logic of the . - /// - /// The encapsulated query logic. - /// - /// A task that represents the asynchronous operation. - /// The task result contains the , or . - /// - [Obsolete] - Task GetBySpecAsync(ISpecification specification, CancellationToken cancellationToken = default); - - /// - /// Finds an entity that matches the encapsulated query logic of the . - /// - /// The type of the result. - /// The encapsulated query logic. - /// - /// A task that represents the asynchronous operation. - /// The task result contains the . - /// - [Obsolete] - Task GetBySpecAsync(ISpecification specification, CancellationToken cancellationToken = default); - - /// - /// Returns the first element of a sequence, or a default value if the sequence contains no elements. - /// - /// The encapsulated query logic. - /// A to observe while waiting for the task to complete. - /// - /// A task that represents the asynchronous operation. - /// The task result contains the , or . - /// - Task FirstOrDefaultAsync(ISpecification specification, CancellationToken cancellationToken = default); - - /// - /// Returns the first element of a sequence, or a default value if the sequence contains no elements. - /// - /// The encapsulated query logic. - /// A to observe while waiting for the task to complete. - /// - /// A task that represents the asynchronous operation. - /// The task result contains the , or . - /// - Task FirstOrDefaultAsync(ISpecification specification, CancellationToken cancellationToken = default); - - /// - /// Returns the only element of a sequence, or a default value if the sequence is empty; this method throws an exception if there is more than one element in the sequence. - /// - /// The encapsulated query logic. - /// A to observe while waiting for the task to complete. - /// - /// A task that represents the asynchronous operation. - /// The task result contains the , or . - /// - Task SingleOrDefaultAsync(ISingleResultSpecification specification, CancellationToken cancellationToken = default); - - /// - /// Returns the only element of a sequence, or a default value if the sequence is empty; this method throws an exception if there is more than one element in the sequence. - /// - /// The encapsulated query logic. - /// A to observe while waiting for the task to complete. - /// - /// A task that represents the asynchronous operation. - /// The task result contains the , or . - /// - Task SingleOrDefaultAsync(ISingleResultSpecification specification, CancellationToken cancellationToken = default); - - /// - /// Finds all entities of from the database. - /// - /// - /// A task that represents the asynchronous operation. - /// The task result contains a that contains elements from the input sequence. - /// - Task> ListAsync(CancellationToken cancellationToken = default); - - /// - /// Finds all entities of , that matches the encapsulated query logic of the - /// , from the database. - /// - /// The encapsulated query logic. - /// - /// A task that represents the asynchronous operation. - /// The task result contains a that contains elements from the input sequence. - /// - Task> ListAsync(ISpecification specification, CancellationToken cancellationToken = default); - - /// - /// Finds all entities of , that matches the encapsulated query logic of the - /// , from the database. - /// - /// Projects each entity into a new form, being . - /// - /// - /// The type of the value returned by the projection. - /// The encapsulated query logic. - /// - /// A task that represents the asynchronous operation. - /// The task result contains a that contains elements from the input sequence. - /// - Task> ListAsync(ISpecification specification, CancellationToken cancellationToken = default); - - /// - /// Returns a number that represents how many entities satisfy the encapsulated query logic - /// of the . - /// - /// The encapsulated query logic. - /// - /// A task that represents the asynchronous operation. The task result contains the - /// number of elements in the input sequence. - /// - Task CountAsync(ISpecification specification, CancellationToken cancellationToken = default); - - /// - /// Returns the total number of records. - /// - /// - /// A task that represents the asynchronous operation. The task result contains the - /// number of elements in the input sequence. - /// - Task CountAsync(CancellationToken cancellationToken = default); - - /// - /// Returns a boolean that represents whether any entity satisfy the encapsulated query logic - /// of the or not. - /// - /// The encapsulated query logic. - /// - /// A task that represents the asynchronous operation. The task result contains true if the - /// source sequence contains any elements; otherwise, false. - /// - Task AnyAsync(ISpecification specification, CancellationToken cancellationToken = default); - - /// - /// Returns a boolean whether any entity exists or not. - /// - /// - /// A task that represents the asynchronous operation. The task result contains true if the - /// source sequence contains any elements; otherwise, false. - /// - Task AnyAsync(CancellationToken cancellationToken = default); + /// The type of the value returned by the projection. + /// The encapsulated query logic. + /// + /// A task that represents the asynchronous operation. + /// The task result contains a that contains elements from the input sequence. + /// + Task> ListAsync(ISpecification specification, CancellationToken cancellationToken = default); + + /// + /// Returns a number that represents how many entities satisfy the encapsulated query logic + /// of the . + /// + /// The encapsulated query logic. + /// + /// A task that represents the asynchronous operation. The task result contains the + /// number of elements in the input sequence. + /// + Task CountAsync(ISpecification specification, CancellationToken cancellationToken = default); + + /// + /// Returns the total number of records. + /// + /// + /// A task that represents the asynchronous operation. The task result contains the + /// number of elements in the input sequence. + /// + Task CountAsync(CancellationToken cancellationToken = default); + + /// + /// Returns a boolean that represents whether any entity satisfy the encapsulated query logic + /// of the or not. + /// + /// The encapsulated query logic. + /// + /// A task that represents the asynchronous operation. The task result contains true if the + /// source sequence contains any elements; otherwise, false. + /// + Task AnyAsync(ISpecification specification, CancellationToken cancellationToken = default); + + /// + /// Returns a boolean whether any entity exists or not. + /// + /// + /// A task that represents the asynchronous operation. The task result contains true if the + /// source sequence contains any elements; otherwise, false. + /// + Task AnyAsync(CancellationToken cancellationToken = default); #if NET6_0_OR_GREATER - /// - /// Finds all entities of , that matches the encapsulated query logic of the - /// , from the database. - /// - /// The encapsulated query logic. - /// - /// Returns an IAsyncEnumerable which can be enumerated asynchronously. - /// - IAsyncEnumerable AsAsyncEnumerable(ISpecification specification); + /// + /// Finds all entities of , that matches the encapsulated query logic of the + /// , from the database. + /// + /// The encapsulated query logic. + /// + /// Returns an IAsyncEnumerable which can be enumerated asynchronously. + /// + IAsyncEnumerable AsAsyncEnumerable(ISpecification specification); #endif - } } diff --git a/Specification/src/Ardalis.Specification/IRepositoryBase.cs b/Specification/src/Ardalis.Specification/IRepositoryBase.cs index 4ab72502..96ad7149 100644 --- a/Specification/src/Ardalis.Specification/IRepositoryBase.cs +++ b/Specification/src/Ardalis.Specification/IRepositoryBase.cs @@ -2,73 +2,71 @@ using System.Threading; using System.Threading.Tasks; -namespace Ardalis.Specification -{ +namespace Ardalis.Specification; + +/// +/// +/// A can be used to query and save instances of . +/// An (or derived) is used to encapsulate the LINQ queries against the database. +/// +/// +/// The type of entity being operated on by this repository. +public interface IRepositoryBase : IReadRepositoryBase where T : class +{ /// - /// - /// A can be used to query and save instances of . - /// An (or derived) is used to encapsulate the LINQ queries against the database. - /// + /// Adds an entity in the database. /// - /// The type of entity being operated on by this repository. - public interface IRepositoryBase : IReadRepositoryBase where T : class - { - /// - /// Adds an entity in the database. - /// - /// The entity to add. - /// - /// - /// A task that represents the asynchronous operation. - /// The task result contains the . - /// - Task AddAsync(T entity, CancellationToken cancellationToken = default); + /// The entity to add. + /// + /// + /// A task that represents the asynchronous operation. + /// The task result contains the . + /// + Task AddAsync(T entity, CancellationToken cancellationToken = default); - /// - /// Adds the given entities in the database - /// - /// - /// - /// - /// A task that represents the asynchronous operation. - /// The task result contains the . - /// - Task> AddRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default); + /// + /// Adds the given entities in the database + /// + /// + /// + /// + /// A task that represents the asynchronous operation. + /// + Task> AddRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default); - /// - /// Updates an entity in the database - /// - /// The entity to update. - /// A task that represents the asynchronous operation. - Task UpdateAsync(T entity, CancellationToken cancellationToken = default); + /// + /// Updates an entity in the database + /// + /// The entity to update. + /// A task that represents the asynchronous operation. + Task UpdateAsync(T entity, CancellationToken cancellationToken = default); - /// - /// Updates the given entities in the database - /// - /// The entities to update. - /// - /// A task that represents the asynchronous operation. - Task UpdateRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default); + /// + /// Updates the given entities in the database + /// + /// The entities to update. + /// + /// A task that represents the asynchronous operation. + Task UpdateRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default); - /// - /// Removes an entity in the database - /// - /// The entity to delete. - /// A task that represents the asynchronous operation. - Task DeleteAsync(T entity, CancellationToken cancellationToken = default); + /// + /// Removes an entity in the database + /// + /// The entity to delete. + /// A task that represents the asynchronous operation. + Task DeleteAsync(T entity, CancellationToken cancellationToken = default); - /// - /// Removes the given entities in the database - /// - /// The entities to remove. - /// A task that represents the asynchronous operation. - Task DeleteRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default); + /// + /// Removes the given entities in the database + /// + /// The entities to remove. + /// A task that represents the asynchronous operation. + Task DeleteRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default); - /// - /// Persists changes to the database. - /// - /// A task that represents the asynchronous operation. - Task SaveChangesAsync(CancellationToken cancellationToken = default); - } + /// + /// Persists changes to the database. + /// + /// A task that represents the asynchronous operation. + Task SaveChangesAsync(CancellationToken cancellationToken = default); } diff --git a/Specification/src/Ardalis.Specification/ISingleResultSpecification.cs b/Specification/src/Ardalis.Specification/ISingleResultSpecification.cs index 407d69eb..7fbaebde 100644 --- a/Specification/src/Ardalis.Specification/ISingleResultSpecification.cs +++ b/Specification/src/Ardalis.Specification/ISingleResultSpecification.cs @@ -1,31 +1,30 @@ using System; -namespace Ardalis.Specification +namespace Ardalis.Specification; + +/// +/// A marker interface for specifications that are meant to return a single entity. Used to constrain methods +/// that accept a Specification and return a single result rather than a collection of results. +/// +[Obsolete("Use ISingleResultSpecification instead. This interface will be removed in a future version of Ardalis.Specification.")] +public interface ISingleResultSpecification { - /// - /// A marker interface for specifications that are meant to return a single entity. Used to constrain methods - /// that accept a Specification and return a single result rather than a collection of results. - /// - [Obsolete("Use ISingleResultSpecification instead. This interface will be removed in a future version of Ardalis.Specification.")] - public interface ISingleResultSpecification - { - } +} - /// - /// Encapsulates query logic for . It is meant to return a single result. - /// - /// The type being queried against. - public interface ISingleResultSpecification : ISpecification//, ISingleResultSpecification - { - } +/// +/// Encapsulates query logic for . It is meant to return a single result. +/// +/// The type being queried against. +public interface ISingleResultSpecification : ISpecification//, ISingleResultSpecification +{ +} - /// - /// Encapsulates query logic for , - /// and projects the result into . It is meant to return a single result. - /// - /// The type being queried against. - /// The type of the result. - public interface ISingleResultSpecification : ISpecification//, ISingleResultSpecification - { - } +/// +/// Encapsulates query logic for , +/// and projects the result into . It is meant to return a single result. +/// +/// The type being queried against. +/// The type of the result. +public interface ISingleResultSpecification : ISpecification//, ISingleResultSpecification +{ } diff --git a/Specification/src/Ardalis.Specification/ISpecification.cs b/Specification/src/Ardalis.Specification/ISpecification.cs index d0ed1609..24304d36 100644 --- a/Specification/src/Ardalis.Specification/ISpecification.cs +++ b/Specification/src/Ardalis.Specification/ISpecification.cs @@ -2,154 +2,153 @@ using System.Collections.Generic; using System.Linq.Expressions; -namespace Ardalis.Specification +namespace Ardalis.Specification; + +/// +/// Encapsulates query logic for , +/// and projects the result into . +/// +/// The type being queried against. +/// The type of the result. +public interface ISpecification : ISpecification { + new ISpecificationBuilder Query { get; } + + /// + /// The Select transform function to apply to the element. + /// + Expression>? Selector { get; } + + /// + /// The SelectMany transform function to apply to the element. + /// + Expression>>? SelectorMany { get; } + + /// + /// The transform function to apply to the result of the query encapsulated by the . + /// + new Func, IEnumerable>? PostProcessingAction { get; } + + new IEnumerable Evaluate(IEnumerable entities); +} + +/// +/// Encapsulates query logic for . +/// +/// The type being queried against. +public interface ISpecification +{ + ISpecificationBuilder Query { get; } + + /// + /// Arbitrary state to be accessed from builders and evaluators. + /// + IDictionary Items { get; set; } + + /// + /// The collection of filters. + /// + IEnumerable> WhereExpressions { get; } + + /// + /// The collections of functions used to determine the sorting (and subsequent sorting), + /// to apply to the result of the query encapsulated by the . + /// + IEnumerable> OrderExpressions { get; } + + /// + /// The collection of s describing each include expression. + /// This information is utilized to build Include/ThenInclude functions in the query. + /// + IEnumerable IncludeExpressions { get; } + + /// + /// The collection of navigation properties, as strings, to include in the query. + /// + IEnumerable IncludeStrings { get; } + + /// + /// The collection of 'SQL LIKE' operations. + /// + IEnumerable> SearchCriterias { get; } + + /// + /// The number of elements to return. + /// + int? Take { get; } + + /// + /// The number of elements to skip before returning the remaining elements. + /// + int? Skip { get; } + + /// + /// The transform function to apply to the result of the query encapsulated by the . + /// + Func, IEnumerable>? PostProcessingAction { get; } + + /// + /// Return whether or not the results should be cached. + /// + bool CacheEnabled { get; } + + /// + /// The identifier to use to store and retrieve results from the cache. + /// + string? CacheKey { get; } + + /// + /// Returns whether or not the change tracker will track any of the entities + /// that are returned. + /// + bool AsTracking { get; } + /// - /// Encapsulates query logic for , - /// and projects the result into . - /// - /// The type being queried against. - /// The type of the result. - public interface ISpecification : ISpecification - { - ISpecificationBuilder Query { get; } - - /// - /// The Select transform function to apply to the element. - /// - Expression>? Selector { get; } - - /// - /// The SelectMany transform function to apply to the element. - /// - Expression>>? SelectorMany { get; } - - /// - /// The transform function to apply to the result of the query encapsulated by the . - /// - new Func, IEnumerable>? PostProcessingAction { get; } - - new IEnumerable Evaluate(IEnumerable entities); - } - - /// - /// Encapsulates query logic for . - /// - /// The type being queried against. - public interface ISpecification - { - ISpecificationBuilder Query { get; } - - /// - /// Arbitrary state to be accessed from builders and evaluators. - /// - IDictionary Items { get; set; } - - /// - /// The collection of filters. - /// - IEnumerable> WhereExpressions { get; } - - /// - /// The collections of functions used to determine the sorting (and subsequent sorting), - /// to apply to the result of the query encapsulated by the . - /// - IEnumerable> OrderExpressions { get; } - - /// - /// The collection of s describing each include expression. - /// This information is utilized to build Include/ThenInclude functions in the query. - /// - IEnumerable IncludeExpressions { get; } - - /// - /// The collection of navigation properties, as strings, to include in the query. - /// - IEnumerable IncludeStrings { get; } - - /// - /// The collection of 'SQL LIKE' operations. - /// - IEnumerable> SearchCriterias { get; } - - /// - /// The number of elements to return. - /// - int? Take { get; } - - /// - /// The number of elements to skip before returning the remaining elements. - /// - int? Skip { get; } - - /// - /// The transform function to apply to the result of the query encapsulated by the . - /// - Func, IEnumerable>? PostProcessingAction { get; } - - /// - /// Return whether or not the results should be cached. - /// - bool CacheEnabled { get; } - - /// - /// The identifier to use to store and retrieve results from the cache. - /// - string? CacheKey { get; } - - /// - /// Returns whether or not the change tracker will track any of the entities - /// that are returned. - /// - bool AsTracking { get; } - - /// - /// Returns whether or not the change tracker will track any of the entities - /// that are returned. When true, if the entity instances are modified, this will not be detected - /// by the change tracker. - /// - bool AsNoTracking { get; } - - /// - /// Returns whether or not the generated sql query should be split into multiple SQL queries - /// - /// - /// This feature was introduced in EF Core 5.0. It only works when using Include - /// for more info: https://docs.microsoft.com/en-us/ef/core/querying/single-split-queries - /// - bool AsSplitQuery { get; } - - /// - /// Returns whether or not the query will then keep track of returned instances - /// (without tracking them in the normal way) - /// and ensure no duplicates are created in the query results - /// - /// - /// for more info: https://docs.microsoft.com/en-us/ef/core/change-tracking/identity-resolution#identity-resolution-and-queries - /// - 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 - /// - /// the list of entities to which the specification will be applied - /// - IEnumerable Evaluate(IEnumerable entities); - - /// - /// It returns whether the given entity satisfies the conditions of the specification. - /// - /// The entity to be validated - /// - bool IsSatisfiedBy(T entity); - } + /// Returns whether or not the change tracker will track any of the entities + /// that are returned. When true, if the entity instances are modified, this will not be detected + /// by the change tracker. + /// + bool AsNoTracking { get; } + + /// + /// Returns whether or not the generated sql query should be split into multiple SQL queries + /// + /// + /// This feature was introduced in EF Core 5.0. It only works when using Include + /// for more info: https://docs.microsoft.com/en-us/ef/core/querying/single-split-queries + /// + bool AsSplitQuery { get; } + + /// + /// Returns whether or not the query will then keep track of returned instances + /// (without tracking them in the normal way) + /// and ensure no duplicates are created in the query results + /// + /// + /// for more info: https://docs.microsoft.com/en-us/ef/core/change-tracking/identity-resolution#identity-resolution-and-queries + /// + 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 + /// + /// the list of entities to which the specification will be applied + /// + IEnumerable Evaluate(IEnumerable entities); + + /// + /// It returns whether the given entity satisfies the conditions of the specification. + /// + /// The entity to be validated + /// + bool IsSatisfiedBy(T entity); } diff --git a/Specification/src/Ardalis.Specification/IncludeTypeEnum.cs b/Specification/src/Ardalis.Specification/IncludeTypeEnum.cs index 7a99c3bb..98d160cf 100644 --- a/Specification/src/Ardalis.Specification/IncludeTypeEnum.cs +++ b/Specification/src/Ardalis.Specification/IncludeTypeEnum.cs @@ -1,12 +1,7 @@ -using System; -using System.Collections.Generic; -using System.Text; +namespace Ardalis.Specification; -namespace Ardalis.Specification +public enum IncludeTypeEnum { - public enum IncludeTypeEnum - { - Include = 1, - ThenInclude = 2 - } + Include = 1, + ThenInclude = 2 } diff --git a/Specification/src/Ardalis.Specification/OrderTypeEnum.cs b/Specification/src/Ardalis.Specification/OrderTypeEnum.cs index d645c398..606dad83 100644 --- a/Specification/src/Ardalis.Specification/OrderTypeEnum.cs +++ b/Specification/src/Ardalis.Specification/OrderTypeEnum.cs @@ -1,17 +1,12 @@ -using System; -using System.Collections.Generic; -using System.Text; +namespace Ardalis.Specification; -namespace Ardalis.Specification +/// +/// Whether to (subsequently) sort ascending or descending. +/// +public enum OrderTypeEnum { - /// - /// Whether to (subsequently) sort ascending or descending. - /// - public enum OrderTypeEnum - { - OrderBy = 1, - OrderByDescending = 2, - ThenBy = 3, - ThenByDescending = 4 - } + OrderBy = 1, + OrderByDescending = 2, + ThenBy = 3, + ThenByDescending = 4 } diff --git a/Specification/src/Ardalis.Specification/SingleResultSpecification.cs b/Specification/src/Ardalis.Specification/SingleResultSpecification.cs index ce055704..19b6f4ed 100644 --- a/Specification/src/Ardalis.Specification/SingleResultSpecification.cs +++ b/Specification/src/Ardalis.Specification/SingleResultSpecification.cs @@ -1,12 +1,11 @@ -namespace Ardalis.Specification +namespace Ardalis.Specification; + +/// +public class SingleResultSpecification : Specification, ISingleResultSpecification { - /// - public class SingleResultSpecification : Specification, ISingleResultSpecification - { - } +} - /// - public class SingleResultSpecification : Specification, ISingleResultSpecification - { - } +/// +public class SingleResultSpecification : Specification, ISingleResultSpecification +{ } diff --git a/Specification/src/Ardalis.Specification/Specification.cs b/Specification/src/Ardalis.Specification/Specification.cs index 02019ae9..fc9e18e0 100644 --- a/Specification/src/Ardalis.Specification/Specification.cs +++ b/Specification/src/Ardalis.Specification/Specification.cs @@ -2,125 +2,124 @@ using System.Collections.Generic; using System.Linq.Expressions; -namespace Ardalis.Specification +namespace Ardalis.Specification; + +/// +public class Specification : Specification, ISpecification { - /// - public class Specification : Specification, ISpecification + public new virtual ISpecificationBuilder Query { get; } + + protected Specification() + : this(InMemorySpecificationEvaluator.Default) { - public new virtual ISpecificationBuilder Query { get; } + } - protected Specification() - : this(InMemorySpecificationEvaluator.Default) - { - } + protected Specification(IInMemorySpecificationEvaluator inMemorySpecificationEvaluator) + : base(inMemorySpecificationEvaluator) + { + Query = new SpecificationBuilder(this); + } - protected Specification(IInMemorySpecificationEvaluator inMemorySpecificationEvaluator) - : base(inMemorySpecificationEvaluator) - { - this.Query = new SpecificationBuilder(this); - } + public new virtual IEnumerable Evaluate(IEnumerable entities) + { + return Evaluator.Evaluate(entities, this); + } - public new virtual IEnumerable Evaluate(IEnumerable entities) - { - return Evaluator.Evaluate(entities, this); - } + /// + public Expression>? Selector { get; internal set; } - /// - public Expression>? Selector { get; internal set; } + /// + public Expression>>? SelectorMany { get; internal set; } - /// - public Expression>>? SelectorMany { get; internal set; } + /// + public new Func, IEnumerable>? PostProcessingAction { get; internal set; } = null; +} - /// - public new Func, IEnumerable>? PostProcessingAction { get; internal set; } = null; - } +/// +public class Specification : ISpecification +{ + protected IInMemorySpecificationEvaluator Evaluator { get; } + protected ISpecificationValidator Validator { get; } + public virtual ISpecificationBuilder Query { get; } - /// - public class Specification : ISpecification + protected Specification() + : this(InMemorySpecificationEvaluator.Default, SpecificationValidator.Default) { - protected IInMemorySpecificationEvaluator Evaluator { get; } - protected ISpecificationValidator Validator { get; } - public virtual ISpecificationBuilder Query { get; } - - protected Specification() - : this(InMemorySpecificationEvaluator.Default, SpecificationValidator.Default) - { - } + } - protected Specification(IInMemorySpecificationEvaluator inMemorySpecificationEvaluator) - : this(inMemorySpecificationEvaluator, SpecificationValidator.Default) - { - } + protected Specification(IInMemorySpecificationEvaluator inMemorySpecificationEvaluator) + : this(inMemorySpecificationEvaluator, SpecificationValidator.Default) + { + } - protected Specification(ISpecificationValidator specificationValidator) - : this(InMemorySpecificationEvaluator.Default, specificationValidator) - { - } + protected Specification(ISpecificationValidator specificationValidator) + : this(InMemorySpecificationEvaluator.Default, specificationValidator) + { + } - protected Specification(IInMemorySpecificationEvaluator inMemorySpecificationEvaluator, ISpecificationValidator specificationValidator) - { - this.Evaluator = inMemorySpecificationEvaluator; - this.Validator = specificationValidator; - this.Query = new SpecificationBuilder(this); - } + protected Specification(IInMemorySpecificationEvaluator inMemorySpecificationEvaluator, ISpecificationValidator specificationValidator) + { + Evaluator = inMemorySpecificationEvaluator; + Validator = specificationValidator; + Query = new SpecificationBuilder(this); + } - /// - public virtual IEnumerable Evaluate(IEnumerable entities) - { - return Evaluator.Evaluate(entities, this); - } + /// + public virtual IEnumerable Evaluate(IEnumerable entities) + { + return Evaluator.Evaluate(entities, this); + } - /// - public virtual bool IsSatisfiedBy(T entity) - { - return Validator.IsValid(entity, this); - } + /// + public virtual bool IsSatisfiedBy(T entity) + { + return Validator.IsValid(entity, this); + } - /// - public IDictionary Items { get; set; } = new Dictionary(); + /// + public IDictionary Items { get; set; } = new Dictionary(); - /// - public IEnumerable> WhereExpressions { get; } = new List>(); + /// + public IEnumerable> WhereExpressions { get; } = new List>(); - public IEnumerable> OrderExpressions { get; } = new List>(); + public IEnumerable> OrderExpressions { get; } = new List>(); - /// - public IEnumerable IncludeExpressions { get; } = new List(); + /// + public IEnumerable IncludeExpressions { get; } = new List(); - /// - public IEnumerable IncludeStrings { get; } = new List(); + /// + public IEnumerable IncludeStrings { get; } = new List(); - /// - public IEnumerable> SearchCriterias { get; } = new List>(); + /// + public IEnumerable> SearchCriterias { get; } = new List>(); - /// - public int? Take { get; internal set; } = null; + /// + public int? Take { get; internal set; } = null; - /// - public int? Skip { get; internal set; } = null; + /// + public int? Skip { get; internal set; } = null; - /// - public Func, IEnumerable>? PostProcessingAction { get; internal set; } = null; + /// + public Func, IEnumerable>? PostProcessingAction { get; internal set; } = null; - /// - public string? CacheKey { get; internal set; } + /// + public string? CacheKey { get; internal set; } - /// - public bool CacheEnabled { get; internal set; } + /// + public bool CacheEnabled { get; internal set; } - /// - public bool AsTracking { get; internal set; } = false; + /// + public bool AsTracking { get; internal set; } = false; - /// - public bool AsNoTracking { get; internal set; } = false; + /// + public bool AsNoTracking { get; internal set; } = false; - /// - public bool AsSplitQuery { get; internal set; } = false; + /// + public bool AsSplitQuery { get; internal set; } = false; - /// - public bool AsNoTrackingWithIdentityResolution { get; internal set; } = false; + /// + public bool AsNoTrackingWithIdentityResolution { get; internal set; } = false; - /// - public bool IgnoreQueryFilters { get; internal set; } = false; - } + /// + public bool IgnoreQueryFilters { get; internal set; } = false; } diff --git a/Specification/src/Ardalis.Specification/Validators/ISpecificationValidator.cs b/Specification/src/Ardalis.Specification/Validators/ISpecificationValidator.cs index c7b2914f..8156cb64 100644 --- a/Specification/src/Ardalis.Specification/Validators/ISpecificationValidator.cs +++ b/Specification/src/Ardalis.Specification/Validators/ISpecificationValidator.cs @@ -1,11 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Text; +namespace Ardalis.Specification; -namespace Ardalis.Specification +public interface ISpecificationValidator { - public interface ISpecificationValidator - { - bool IsValid(T entity, ISpecification specification); - } + bool IsValid(T entity, ISpecification specification); } diff --git a/Specification/src/Ardalis.Specification/Validators/IValidator.cs b/Specification/src/Ardalis.Specification/Validators/IValidator.cs index 952a088b..b284636c 100644 --- a/Specification/src/Ardalis.Specification/Validators/IValidator.cs +++ b/Specification/src/Ardalis.Specification/Validators/IValidator.cs @@ -1,11 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Text; +namespace Ardalis.Specification; -namespace Ardalis.Specification +public interface IValidator { - public interface IValidator - { - bool IsValid(T entity, ISpecification specification); - } + bool IsValid(T entity, ISpecification specification); } diff --git a/Specification/src/Ardalis.Specification/Validators/SearchValidator.cs b/Specification/src/Ardalis.Specification/Validators/SearchValidator.cs index 1cec047f..93a48d4d 100644 --- a/Specification/src/Ardalis.Specification/Validators/SearchValidator.cs +++ b/Specification/src/Ardalis.Specification/Validators/SearchValidator.cs @@ -1,23 +1,19 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; +using System.Linq; -namespace Ardalis.Specification +namespace Ardalis.Specification; + +public class SearchValidator : IValidator { - public class SearchValidator : IValidator - { - private SearchValidator() { } - public static SearchValidator Instance { get; } = new SearchValidator(); + private SearchValidator() { } + public static SearchValidator Instance { get; } = new SearchValidator(); - public bool IsValid(T entity, ISpecification specification) + public bool IsValid(T entity, ISpecification specification) + { + foreach (var searchGroup in specification.SearchCriterias.GroupBy(x => x.SearchGroup)) { - foreach (var searchGroup in specification.SearchCriterias.GroupBy(x => x.SearchGroup)) - { - if (searchGroup.Any(c => c.SelectorFunc(entity).Like(c.SearchTerm)) == false) return false; - } - - return true; + if (searchGroup.Any(c => c.SelectorFunc(entity).Like(c.SearchTerm)) == false) return false; } + + return true; } } diff --git a/Specification/src/Ardalis.Specification/Validators/SpecificationValidator.cs b/Specification/src/Ardalis.Specification/Validators/SpecificationValidator.cs index 6ec6498e..c88d5ee8 100644 --- a/Specification/src/Ardalis.Specification/Validators/SpecificationValidator.cs +++ b/Specification/src/Ardalis.Specification/Validators/SpecificationValidator.cs @@ -1,37 +1,34 @@ -using System; -using System.Collections.Generic; -using System.Text; +using System.Collections.Generic; -namespace Ardalis.Specification +namespace Ardalis.Specification; + +public class SpecificationValidator : ISpecificationValidator { - public class SpecificationValidator : ISpecificationValidator - { - // Will use singleton for default configuration. Yet, it can be instantiated if necessary, with default or provided validators. - public static SpecificationValidator Default { get; } = new SpecificationValidator(); + // Will use singleton for default configuration. Yet, it can be instantiated if necessary, with default or provided validators. + public static SpecificationValidator Default { get; } = new SpecificationValidator(); - private readonly List validators = new List(); + private readonly List _validators = new(); - public SpecificationValidator() - { - this.validators.AddRange(new IValidator[] - { - WhereValidator.Instance, - SearchValidator.Instance - }); - } - public SpecificationValidator(IEnumerable validators) + public SpecificationValidator() + { + _validators.AddRange(new IValidator[] { - this.validators.AddRange(validators); - } + WhereValidator.Instance, + SearchValidator.Instance + }); + } + public SpecificationValidator(IEnumerable validators) + { + _validators.AddRange(validators); + } - public virtual bool IsValid(T entity, ISpecification specification) + public virtual bool IsValid(T entity, ISpecification specification) + { + foreach (var partialValidator in _validators) { - foreach (var partialValidator in validators) - { - if (partialValidator.IsValid(entity, specification) == false) return false; - } - - return true; + if (partialValidator.IsValid(entity, specification) == false) return false; } + + return true; } } diff --git a/Specification/src/Ardalis.Specification/Validators/WhereValidator.cs b/Specification/src/Ardalis.Specification/Validators/WhereValidator.cs index 4b31f3a1..4e7778d4 100644 --- a/Specification/src/Ardalis.Specification/Validators/WhereValidator.cs +++ b/Specification/src/Ardalis.Specification/Validators/WhereValidator.cs @@ -1,22 +1,17 @@ -using System; -using System.Collections.Generic; -using System.Text; +namespace Ardalis.Specification; -namespace Ardalis.Specification +public class WhereValidator : IValidator { - public class WhereValidator : IValidator - { - private WhereValidator() { } - public static WhereValidator Instance { get; } = new WhereValidator(); + private WhereValidator() { } + public static WhereValidator Instance { get; } = new WhereValidator(); - public bool IsValid(T entity, ISpecification specification) + public bool IsValid(T entity, ISpecification specification) + { + foreach (var info in specification.WhereExpressions) { - foreach (var info in specification.WhereExpressions) - { - if (info.FilterFunc(entity) == false) return false; - } - - return true; + if (info.FilterFunc(entity) == false) return false; } + + return true; } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Ardalis.Specification.UnitTests.csproj b/Specification/tests/Ardalis.Specification.UnitTests/Ardalis.Specification.UnitTests.csproj index b10bf14a..5ec1e566 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Ardalis.Specification.UnitTests.csproj +++ b/Specification/tests/Ardalis.Specification.UnitTests/Ardalis.Specification.UnitTests.csproj @@ -1,29 +1,35 @@  - net6.0;net472 - false + net7.0;net472 + 11.0 enable - 9.0 + false - - runtime; build; native; contentfiles; analyzers + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + + + + + + + 1701;1702;1591;1573;1712;0618 + diff --git a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/IncludableBuilderExtensions_ThenInclude.cs b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/IncludableBuilderExtensions_ThenInclude.cs index 41a7817c..986f3549 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/IncludableBuilderExtensions_ThenInclude.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/IncludableBuilderExtensions_ThenInclude.cs @@ -1,55 +1,49 @@ using System.Collections.Generic; -using System.Linq; -using Ardalis.Specification.UnitTests.Fixture.Entities; -using Ardalis.Specification.UnitTests.Fixture.Specs; -using FluentAssertions; -using Xunit; -namespace Ardalis.Specification.UnitTests +namespace Ardalis.Specification.UnitTests; + +public class IncludableBuilderExtensions_ThenInclude { - public class IncludableBuilderExtensions_ThenInclude + [Fact] + public void AppendIncludeExpressionInfoToListWithTypeThenInclude_GivenThenIncludeExpression() { - [Fact] - public void AppendIncludeExpressionInfoToListWithTypeThenInclude_GivenThenIncludeExpression() - { - var spec = new StoreIncludeCompanyThenCountrySpec(); + var spec = new StoreIncludeCompanyThenCountrySpec(); - var includeExpressions = spec.IncludeExpressions.ToList(); + var includeExpressions = spec.IncludeExpressions.ToList(); - // The list must have two items, since ThenInclude can be applied once the first level is applied. - includeExpressions.Should().HaveCount(2); + // The list must have two items, since ThenInclude can be applied once the first level is applied. + includeExpressions.Should().HaveCount(2); - includeExpressions[1].Type.Should().Be(IncludeTypeEnum.ThenInclude); - } + includeExpressions[1].Type.Should().Be(IncludeTypeEnum.ThenInclude); + } - [Fact] - public void AddsNothingToList_GivenDiscardedIncludeChain() - { - var spec = new CompanyByIdWithFalseConditions(1); + [Fact] + public void AddsNothingToList_GivenDiscardedIncludeChain() + { + var spec = new CompanyByIdWithFalseConditions(1); - spec.IncludeExpressions.Should().BeEmpty(); - } + spec.IncludeExpressions.Should().BeEmpty(); + } - [Fact] - public void AddsNothingToList_GivenThenIncludeExpressionWithFalseCondition() - { - var spec = new CompanyByIdWithFalseConditionsForInnerChains(1); + [Fact] + public void AddsNothingToList_GivenThenIncludeExpressionWithFalseCondition() + { + var spec = new CompanyByIdWithFalseConditionsForInnerChains(1); - spec.IncludeExpressions.Should().HaveCount(1); - spec.IncludeExpressions.First().Type.Should().Be(IncludeTypeEnum.Include); - spec.IncludeExpressions.Where(x => x.Type == IncludeTypeEnum.ThenInclude).Should().BeEmpty(); - } + spec.IncludeExpressions.Should().HaveCount(1); + spec.IncludeExpressions.First().Type.Should().Be(IncludeTypeEnum.Include); + spec.IncludeExpressions.Where(x => x.Type == IncludeTypeEnum.ThenInclude).Should().BeEmpty(); + } - [Fact] - public void ThenInclude_Append_IncludeExpressionInfo_With_EnumerablePreviousPropertyType() - { - var spec = new StoreIncludeCompanyThenStoresSpec(); + [Fact] + public void ThenInclude_Append_IncludeExpressionInfo_With_EnumerablePreviousPropertyType() + { + var spec = new StoreIncludeCompanyThenStoresSpec(); - var includeExpressions = spec.IncludeExpressions.ToList(); + var includeExpressions = spec.IncludeExpressions.ToList(); - includeExpressions.Should().HaveCount(3); + includeExpressions.Should().HaveCount(3); - includeExpressions[2].PreviousPropertyType.Should().Be(typeof(IEnumerable)); - } + includeExpressions[2].PreviousPropertyType.Should().Be(typeof(IEnumerable)); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/OrderedBuilderExtensions_ThenBy.cs b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/OrderedBuilderExtensions_ThenBy.cs index 6b7502df..60d5f291 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/OrderedBuilderExtensions_ThenBy.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/OrderedBuilderExtensions_ThenBy.cs @@ -1,46 +1,36 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Ardalis.Specification.UnitTests.Fixture.Entities; -using Ardalis.Specification.UnitTests.Fixture.Specs; -using FluentAssertions; -using Xunit; - -namespace Ardalis.Specification.UnitTests +namespace Ardalis.Specification.UnitTests; + +public class OrderedBuilderExtensions_ThenBy { - public class OrderedBuilderExtensions_ThenBy + [Fact] + public void AppendOrderExpressionToListWithThenByType_GivenThenByExpression() { - [Fact] - public void AppendOrderExpressionToListWithThenByType_GivenThenByExpression() - { - var spec = new StoresByCompanyOrderedDescByNameThenByIdSpec(1); + var spec = new StoresByCompanyOrderedDescByNameThenByIdSpec(1); - var orderExpressions = spec.OrderExpressions.ToList(); + var orderExpressions = spec.OrderExpressions.ToList(); - // The list must have two items, since Then can be applied once the first level is applied. - orderExpressions.Should().HaveCount(2); + // The list must have two items, since Then can be applied once the first level is applied. + orderExpressions.Should().HaveCount(2); - orderExpressions[1].OrderType.Should().Be(OrderTypeEnum.ThenBy); - } + orderExpressions[1].OrderType.Should().Be(OrderTypeEnum.ThenBy); + } - [Fact] - public void AddsNothingToList_GivenDiscardedOrderChain() - { - var spec = new CompanyByIdWithFalseConditions(1); + [Fact] + public void AddsNothingToList_GivenDiscardedOrderChain() + { + var spec = new CompanyByIdWithFalseConditions(1); - spec.OrderExpressions.Should().BeEmpty(); - } + spec.OrderExpressions.Should().BeEmpty(); + } - [Fact] - public void AddsNothingToList_GivenThenByExpressionWithFalseCondition() - { - var spec = new CompanyByIdWithFalseConditionsForInnerChains(1); + [Fact] + public void AddsNothingToList_GivenThenByExpressionWithFalseCondition() + { + var spec = new CompanyByIdWithFalseConditionsForInnerChains(1); - spec.OrderExpressions.Should().HaveCount(2); - spec.OrderExpressions.First().OrderType.Should().Be(OrderTypeEnum.OrderBy); - spec.OrderExpressions.Skip(1).First().OrderType.Should().Be(OrderTypeEnum.OrderByDescending); - spec.OrderExpressions.Where(x => x.OrderType == OrderTypeEnum.ThenBy).Should().BeEmpty(); - } + spec.OrderExpressions.Should().HaveCount(2); + spec.OrderExpressions.First().OrderType.Should().Be(OrderTypeEnum.OrderBy); + spec.OrderExpressions.Skip(1).First().OrderType.Should().Be(OrderTypeEnum.OrderByDescending); + spec.OrderExpressions.Where(x => x.OrderType == OrderTypeEnum.ThenBy).Should().BeEmpty(); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/OrderedBuilderExtensions_ThenByDescending.cs b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/OrderedBuilderExtensions_ThenByDescending.cs index 0de28e3d..7ac2d4e2 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/OrderedBuilderExtensions_ThenByDescending.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/OrderedBuilderExtensions_ThenByDescending.cs @@ -1,46 +1,36 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Ardalis.Specification.UnitTests.Fixture.Entities; -using Ardalis.Specification.UnitTests.Fixture.Specs; -using FluentAssertions; -using Xunit; - -namespace Ardalis.Specification.UnitTests +namespace Ardalis.Specification.UnitTests; + +public class OrderedBuilderExtensions_ThenByDescending { - public class OrderedBuilderExtensions_ThenByDescending + [Fact] + public void AppendsOrderExpressionToListWithThenByDescendingType_GivenThenByDescendingExpression() { - [Fact] - public void AppendsOrderExpressionToListWithThenByDescendingType_GivenThenByDescendingExpression() - { - var spec = new StoresByCompanyOrderedDescByNameThenByDescIdSpec(1); + var spec = new StoresByCompanyOrderedDescByNameThenByDescIdSpec(1); - var orderExpressions = spec.OrderExpressions.ToList(); + var orderExpressions = spec.OrderExpressions.ToList(); - // The list must have two items, since Then can be applied once the first level is applied. - orderExpressions.Should().HaveCount(2); + // The list must have two items, since Then can be applied once the first level is applied. + orderExpressions.Should().HaveCount(2); - orderExpressions[1].OrderType.Should().Be(OrderTypeEnum.ThenByDescending); - } + orderExpressions[1].OrderType.Should().Be(OrderTypeEnum.ThenByDescending); + } - [Fact] - public void AddsNothingToList_GivenDiscardedOrderChain() - { - var spec = new CompanyByIdWithFalseConditions(1); + [Fact] + public void AddsNothingToList_GivenDiscardedOrderChain() + { + var spec = new CompanyByIdWithFalseConditions(1); - spec.OrderExpressions.Should().BeEmpty(); - } + spec.OrderExpressions.Should().BeEmpty(); + } - [Fact] - public void AddsNothingToList_GivenThenByDescendingExpressionWithFalseCondition() - { - var spec = new CompanyByIdWithFalseConditionsForInnerChains(1); + [Fact] + public void AddsNothingToList_GivenThenByDescendingExpressionWithFalseCondition() + { + var spec = new CompanyByIdWithFalseConditionsForInnerChains(1); - spec.OrderExpressions.Should().HaveCount(2); - spec.OrderExpressions.First().OrderType.Should().Be(OrderTypeEnum.OrderBy); - spec.OrderExpressions.Skip(1).First().OrderType.Should().Be(OrderTypeEnum.OrderByDescending); - spec.OrderExpressions.Where(x => x.OrderType == OrderTypeEnum.ThenByDescending).Should().BeEmpty(); - } + spec.OrderExpressions.Should().HaveCount(2); + spec.OrderExpressions.First().OrderType.Should().Be(OrderTypeEnum.OrderBy); + spec.OrderExpressions.Skip(1).First().OrderType.Should().Be(OrderTypeEnum.OrderByDescending); + spec.OrderExpressions.Where(x => x.OrderType == OrderTypeEnum.ThenByDescending).Should().BeEmpty(); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_AsNoTracking.cs b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_AsNoTracking.cs index dc0ec496..cdb4187a 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_AsNoTracking.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_AsNoTracking.cs @@ -1,41 +1,36 @@ -using Ardalis.Specification.UnitTests.Fixture.Specs; -using FluentAssertions; -using Xunit; +namespace Ardalis.Specification.UnitTests.BuilderTests; -namespace Ardalis.Specification.UnitTests.BuilderTests +public class SpecificationBuilderExtensions_AsNoTracking { - public class SpecificationBuilderExtensions_AsNoTracking + [Fact] + public void DoesNothing_GivenSpecWithoutAsNoTracking() { - [Fact] - public void DoesNothing_GivenSpecWithoutAsNoTracking() - { - var spec = new StoreEmptySpec(); + var spec = new StoreEmptySpec(); - spec.AsNoTracking.Should().Be(false); - } + spec.AsNoTracking.Should().Be(false); + } - [Fact] - public void DoesNothing_GivenAsNoTrackingWithFalseCondition() - { - var spec = new CompanyByIdWithFalseConditions(1); + [Fact] + public void DoesNothing_GivenAsNoTrackingWithFalseCondition() + { + var spec = new CompanyByIdWithFalseConditions(1); - spec.AsNoTracking.Should().Be(false); - } + spec.AsNoTracking.Should().Be(false); + } - [Fact] - public void FlagsAsNoTracking_GivenSpecWithAsNoTracking() - { - var spec = new CompanyByIdAsUntrackedSpec(1); + [Fact] + public void FlagsAsNoTracking_GivenSpecWithAsNoTracking() + { + var spec = new CompanyByIdAsUntrackedSpec(1); - spec.AsNoTracking.Should().Be(true); - } + spec.AsNoTracking.Should().Be(true); + } - [Fact] - public void FlagsAsNoTracking_GivenSpecWithAsTrackingAndEndWithAsNoTracking() - { - var spec = new CompanyByIdWithAsTrackingAsUntrackedSpec(1); + [Fact] + public void FlagsAsNoTracking_GivenSpecWithAsTrackingAndEndWithAsNoTracking() + { + var spec = new CompanyByIdWithAsTrackingAsUntrackedSpec(1); - spec.AsNoTracking.Should().Be(true); - } + spec.AsNoTracking.Should().Be(true); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_AsNoTrackingWithIdentityResolution.cs b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_AsNoTrackingWithIdentityResolution.cs index 3fb6ff80..78a86746 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_AsNoTrackingWithIdentityResolution.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_AsNoTrackingWithIdentityResolution.cs @@ -1,41 +1,36 @@ -using Ardalis.Specification.UnitTests.Fixture.Specs; -using FluentAssertions; -using Xunit; +namespace Ardalis.Specification.UnitTests.BuilderTests; -namespace Ardalis.Specification.UnitTests.BuilderTests +public class SpecificationBuilderExtensions_AsNoTrackingWithIdentityResolution { - public class SpecificationBuilderExtensions_AsNoTrackingWithIdentityResolution + [Fact] + public void DoesNothing_GivenSpecWithoutAsNoTrackingWithIdentityResolution() { - [Fact] - public void DoesNothing_GivenSpecWithoutAsNoTrackingWithIdentityResolution() - { - var spec = new StoreEmptySpec(); + var spec = new StoreEmptySpec(); - spec.AsNoTrackingWithIdentityResolution.Should().Be(false); - } + spec.AsNoTrackingWithIdentityResolution.Should().Be(false); + } - [Fact] - public void DoesNothing_GivenAsNoTrackingWithIdentityResolutionWithFalseCondition() - { - var spec = new CompanyByIdWithFalseConditions(1); + [Fact] + public void DoesNothing_GivenAsNoTrackingWithIdentityResolutionWithFalseCondition() + { + var spec = new CompanyByIdWithFalseConditions(1); - spec.AsNoTrackingWithIdentityResolution.Should().Be(false); - } + spec.AsNoTrackingWithIdentityResolution.Should().Be(false); + } - [Fact] - public void FlagsAsNoTracking_GivenSpecWithAsNoTrackingWithIdentityResolution() - { - var spec = new CompanyByIdAsUntrackedWithIdentityResolutionSpec(1); + [Fact] + public void FlagsAsNoTracking_GivenSpecWithAsNoTrackingWithIdentityResolution() + { + var spec = new CompanyByIdAsUntrackedWithIdentityResolutionSpec(1); - spec.AsNoTrackingWithIdentityResolution.Should().Be(true); - } + spec.AsNoTrackingWithIdentityResolution.Should().Be(true); + } - [Fact] - public void FlagsAsNoTracking_GivenSpecWithAsTrackingAndEndWithAsNoTrackingWithIdentityResolution() - { - var spec = new CompanyByIdWithAsTrackingAsUntrackedWithIdentityResolutionSpec(1); + [Fact] + public void FlagsAsNoTracking_GivenSpecWithAsTrackingAndEndWithAsNoTrackingWithIdentityResolution() + { + var spec = new CompanyByIdWithAsTrackingAsUntrackedWithIdentityResolutionSpec(1); - spec.AsNoTrackingWithIdentityResolution.Should().Be(true); - } + spec.AsNoTrackingWithIdentityResolution.Should().Be(true); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_AsSplitQuery.cs b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_AsSplitQuery.cs index 97b688d1..a8f46e39 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_AsSplitQuery.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_AsSplitQuery.cs @@ -1,33 +1,28 @@ -using Ardalis.Specification.UnitTests.Fixture.Specs; -using FluentAssertions; -using Xunit; +namespace Ardalis.Specification.UnitTests.BuilderTests; -namespace Ardalis.Specification.UnitTests.BuilderTests +public class SpecificationBuilderExtensions_AsSplitQuery { - public class SpecificationBuilderExtensions_AsSplitQuery + [Fact] + public void DoesNothing_GivenSpecWithoutAsSplitQuery() { - [Fact] - public void DoesNothing_GivenSpecWithoutAsSplitQuery() - { - var spec = new StoreEmptySpec(); + var spec = new StoreEmptySpec(); - spec.AsSplitQuery.Should().Be(false); - } + spec.AsSplitQuery.Should().Be(false); + } - [Fact] - public void DoesNothing_GivenAsSplitQueryWithFalseCondition() - { - var spec = new CompanyByIdWithFalseConditions(1); + [Fact] + public void DoesNothing_GivenAsSplitQueryWithFalseCondition() + { + var spec = new CompanyByIdWithFalseConditions(1); - spec.AsSplitQuery.Should().Be(false); - } + spec.AsSplitQuery.Should().Be(false); + } - [Fact] - public void FlagsAsNoTracking_GivenSpecWithAsSplitQuery() - { - var spec = new CompanyByIdAsSplitQuery(1); + [Fact] + public void FlagsAsNoTracking_GivenSpecWithAsSplitQuery() + { + var spec = new CompanyByIdAsSplitQuery(1); - spec.AsSplitQuery.Should().Be(true); - } + spec.AsSplitQuery.Should().Be(true); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_AsTracking.cs b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_AsTracking.cs index 9785bac0..953f3ea3 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_AsTracking.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_AsTracking.cs @@ -1,41 +1,36 @@ -using Ardalis.Specification.UnitTests.Fixture.Specs; -using FluentAssertions; -using Xunit; +namespace Ardalis.Specification.UnitTests.BuilderTests; -namespace Ardalis.Specification.UnitTests.BuilderTests +public class SpecificationBuilderExtensions_AsTracking { - public class SpecificationBuilderExtensions_AsTracking + [Fact] + public void DoesNothing_GivenSpecWithoutAsTracking() { - [Fact] - public void DoesNothing_GivenSpecWithoutAsTracking() - { - var spec = new StoreEmptySpec(); + var spec = new StoreEmptySpec(); - spec.AsTracking.Should().Be(false); - } + spec.AsTracking.Should().Be(false); + } - [Fact] - public void DoesNothing_GivenAsTrackingWithFalseCondition() - { - var spec = new CompanyByIdWithFalseConditions(1); + [Fact] + public void DoesNothing_GivenAsTrackingWithFalseCondition() + { + var spec = new CompanyByIdWithFalseConditions(1); - spec.AsTracking.Should().Be(false); - } + spec.AsTracking.Should().Be(false); + } - [Fact] - public void FlagsAsTracking_GivenSpecWithAsTracking() - { - var spec = new CompanyByIdAsTrackedSpec(1); + [Fact] + public void FlagsAsTracking_GivenSpecWithAsTracking() + { + var spec = new CompanyByIdAsTrackedSpec(1); - spec.AsTracking.Should().Be(true); - } + spec.AsTracking.Should().Be(true); + } - [Fact] - public void FlagsAsTracking_GivenSpecWithAsNoTrackingAndEndWithAsTracking() - { - var spec = new CompanyByIdWithAsNoTrackingAsTrackedSpec(1); + [Fact] + public void FlagsAsTracking_GivenSpecWithAsNoTrackingAndEndWithAsTracking() + { + var spec = new CompanyByIdWithAsNoTrackingAsTrackedSpec(1); - spec.AsTracking.Should().Be(true); - } + spec.AsTracking.Should().Be(true); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_IgnoreQueryFilters.cs b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_IgnoreQueryFilters.cs index be66b0ec..e27ac124 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_IgnoreQueryFilters.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_IgnoreQueryFilters.cs @@ -1,33 +1,28 @@ -using Ardalis.Specification.UnitTests.Fixture.Specs; -using FluentAssertions; -using Xunit; +namespace Ardalis.Specification.UnitTests.BuilderTests; -namespace Ardalis.Specification.UnitTests.BuilderTests +public class SpecificationBuilderExtensions_IgnoreQueryFilters { - public class SpecificationBuilderExtensions_IgnoreQueryFilters + [Fact] + public void DoesNothing_GivenSpecWithoutIgnoreQueryFilters() { - [Fact] - public void DoesNothing_GivenSpecWithoutIgnoreQueryFilters() - { - var spec = new StoreEmptySpec(); + var spec = new StoreEmptySpec(); - spec.IgnoreQueryFilters.Should().Be(false); - } + spec.IgnoreQueryFilters.Should().Be(false); + } - [Fact] - public void DoesNothing_GivenIgnoreQueryFiltersWithFalseCondition() - { - var spec = new CompanyByIdWithFalseConditions(1); + [Fact] + public void DoesNothing_GivenIgnoreQueryFiltersWithFalseCondition() + { + var spec = new CompanyByIdWithFalseConditions(1); - spec.IgnoreQueryFilters.Should().Be(false); - } + spec.IgnoreQueryFilters.Should().Be(false); + } - [Fact] - public void FlagsIgnoreQueryFilters_GivenSpecWithIgnoreQueryFilters() - { - var spec = new CompanyByIdIgnoreQueryFilters(1); + [Fact] + public void FlagsIgnoreQueryFilters_GivenSpecWithIgnoreQueryFilters() + { + var spec = new CompanyByIdIgnoreQueryFilters(1); - spec.IgnoreQueryFilters.Should().Be(true); - } + spec.IgnoreQueryFilters.Should().Be(true); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Include.cs b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Include.cs index 988eed52..beca64de 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Include.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Include.cs @@ -1,39 +1,29 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Ardalis.Specification.UnitTests.Fixture.Entities; -using Ardalis.Specification.UnitTests.Fixture.Specs; -using FluentAssertions; -using Xunit; +namespace Ardalis.Specification.UnitTests; -namespace Ardalis.Specification.UnitTests +public class SpecificationBuilderExtensions_Include { - public class SpecificationBuilderExtensions_Include + [Fact] + public void AddsNothingToList_GivenNoIncludeExpression() { - [Fact] - public void AddsNothingToList_GivenNoIncludeExpression() - { - var spec = new StoreEmptySpec(); + var spec = new StoreEmptySpec(); - spec.IncludeExpressions.Should().BeEmpty(); - } + spec.IncludeExpressions.Should().BeEmpty(); + } - [Fact] - public void AddsNothingToList_GivenIncludeExpressionWithFalseCondition() - { - var spec = new CompanyByIdWithFalseConditions(1); + [Fact] + public void AddsNothingToList_GivenIncludeExpressionWithFalseCondition() + { + var spec = new CompanyByIdWithFalseConditions(1); - spec.IncludeExpressions.Should().BeEmpty(); - } + spec.IncludeExpressions.Should().BeEmpty(); + } - [Fact] - public void AddsIncludeExpressionInfoToListWithTypeInclude_GivenIncludeExpression() - { - var spec = new StoreIncludeAddressSpec(); + [Fact] + public void AddsIncludeExpressionInfoToListWithTypeInclude_GivenIncludeExpression() + { + var spec = new StoreIncludeAddressSpec(); - spec.IncludeExpressions.Should().ContainSingle(); - spec.IncludeExpressions.Single().Type.Should().Be(IncludeTypeEnum.Include); - } + spec.IncludeExpressions.Should().ContainSingle(); + spec.IncludeExpressions.Single().Type.Should().Be(IncludeTypeEnum.Include); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_IncludeString.cs b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_IncludeString.cs index 01274505..b20a4c9c 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_IncludeString.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_IncludeString.cs @@ -1,41 +1,31 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Ardalis.Specification.UnitTests.Fixture.Entities; -using Ardalis.Specification.UnitTests.Fixture.Specs; -using FluentAssertions; -using Xunit; +namespace Ardalis.Specification.UnitTests; -namespace Ardalis.Specification.UnitTests +public class SpecificationBuilderExtensions_IncludeString { - public class SpecificationBuilderExtensions_IncludeString + [Fact] + public void AddsNothingToList_GivenNoIncludeStringExpression() { - [Fact] - public void AddsNothingToList_GivenNoIncludeStringExpression() - { - var spec = new StoreEmptySpec(); + var spec = new StoreEmptySpec(); - spec.WhereExpressions.Should().BeEmpty(); - } + spec.WhereExpressions.Should().BeEmpty(); + } - [Fact] - public void AddsNothingToList_GivenIncludeStringWithFalseCondition() - { - var spec = new CompanyByIdWithFalseConditions(1); + [Fact] + public void AddsNothingToList_GivenIncludeStringWithFalseCondition() + { + var spec = new CompanyByIdWithFalseConditions(1); - spec.IncludeStrings.Should().BeEmpty(); - } + spec.IncludeStrings.Should().BeEmpty(); + } - [Fact] - public void AddsIncludeStringToList_GivenString() - { - var spec = new StoreIncludeCompanyThenCountryAsStringSpec(); + [Fact] + public void AddsIncludeStringToList_GivenString() + { + var spec = new StoreIncludeCompanyThenCountryAsStringSpec(); - var expected = $"{nameof(Company)}.{nameof(Company.Country)}"; + var expected = $"{nameof(Company)}.{nameof(Company.Country)}"; - spec.IncludeStrings.Should().ContainSingle(); - spec.IncludeStrings.Single().Should().Be(expected); - } + spec.IncludeStrings.Should().ContainSingle(); + spec.IncludeStrings.Single().Should().Be(expected); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_OrderBy.cs b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_OrderBy.cs index c351b11c..7c58b511 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_OrderBy.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_OrderBy.cs @@ -1,39 +1,29 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Ardalis.Specification.UnitTests.Fixture.Entities; -using Ardalis.Specification.UnitTests.Fixture.Specs; -using FluentAssertions; -using Xunit; +namespace Ardalis.Specification.UnitTests; -namespace Ardalis.Specification.UnitTests +public class SpecificationBuilderExtensions_OrderBy { - public class SpecificationBuilderExtensions_OrderBy + [Fact] + public void AddsNothingToList_GivenNoOrderExpression() { - [Fact] - public void AddsNothingToList_GivenNoOrderExpression() - { - var spec = new StoreEmptySpec(); + var spec = new StoreEmptySpec(); - spec.OrderExpressions.Should().BeEmpty(); - } + spec.OrderExpressions.Should().BeEmpty(); + } - [Fact] - public void AddsNothingToList_GivenOrderExpressionWithFalseCondition() - { - var spec = new CompanyByIdWithFalseConditions(1); + [Fact] + public void AddsNothingToList_GivenOrderExpressionWithFalseCondition() + { + var spec = new CompanyByIdWithFalseConditions(1); - spec.OrderExpressions.Should().BeEmpty(); - } + spec.OrderExpressions.Should().BeEmpty(); + } - [Fact] - public void AddsOrderExpressionToListWithOrderByType_GivenOrderByExpression() - { - var spec = new StoresOrderedSpecByName(); + [Fact] + public void AddsOrderExpressionToListWithOrderByType_GivenOrderByExpression() + { + var spec = new StoresOrderedSpecByName(); - spec.OrderExpressions.Should().ContainSingle(); - spec.OrderExpressions.Single().OrderType.Should().Be(OrderTypeEnum.OrderBy); - } + spec.OrderExpressions.Should().ContainSingle(); + spec.OrderExpressions.Single().OrderType.Should().Be(OrderTypeEnum.OrderBy); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_OrderByDescending.cs b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_OrderByDescending.cs index 3a59828a..227ffb6f 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_OrderByDescending.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_OrderByDescending.cs @@ -1,39 +1,29 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Ardalis.Specification.UnitTests.Fixture.Entities; -using Ardalis.Specification.UnitTests.Fixture.Specs; -using FluentAssertions; -using Xunit; +namespace Ardalis.Specification.UnitTests; -namespace Ardalis.Specification.UnitTests +public class SpecificationBuilderExtensions_OrderByDescending { - public class SpecificationBuilderExtensions_OrderByDescending + [Fact] + public void AddsNothingToList_GivenNoOrderExpression() { - [Fact] - public void AddsNothingToList_GivenNoOrderExpression() - { - var spec = new StoreEmptySpec(); + var spec = new StoreEmptySpec(); - spec.OrderExpressions.Should().BeEmpty(); - } + spec.OrderExpressions.Should().BeEmpty(); + } - [Fact] - public void AddsNothingToList_GivenOrderExpressionWithFalseCondition() - { - var spec = new CompanyByIdWithFalseConditions(1); + [Fact] + public void AddsNothingToList_GivenOrderExpressionWithFalseCondition() + { + var spec = new CompanyByIdWithFalseConditions(1); - spec.OrderExpressions.Should().BeEmpty(); - } + spec.OrderExpressions.Should().BeEmpty(); + } - [Fact] - public void AddsOrderExpressionToListWithOrderByDescendingType_GivenOrderByDescendingExpression() - { - var spec = new StoresOrderedDescendingByNameSpec(); + [Fact] + public void AddsOrderExpressionToListWithOrderByDescendingType_GivenOrderByDescendingExpression() + { + var spec = new StoresOrderedDescendingByNameSpec(); - spec.OrderExpressions.Should().ContainSingle(); - spec.OrderExpressions.Single().OrderType.Should().Be(OrderTypeEnum.OrderByDescending); - } + spec.OrderExpressions.Should().ContainSingle(); + spec.OrderExpressions.Single().OrderType.Should().Be(OrderTypeEnum.OrderByDescending); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_PostProcessingAction.cs b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_PostProcessingAction.cs index c4f22b0a..58c0d483 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_PostProcessingAction.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_PostProcessingAction.cs @@ -1,46 +1,36 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Ardalis.Specification.UnitTests.Fixture.Entities; -using Ardalis.Specification.UnitTests.Fixture.Specs; -using FluentAssertions; -using Xunit; - -namespace Ardalis.Specification.UnitTests +namespace Ardalis.Specification.UnitTests; + +public class SpecificationBuilderExtensions_PostProcessingAction { - public class SpecificationBuilderExtensions_PostProcessingAction + [Fact] + public void SetsNothing_GivenNoPostProcessingAction() { - [Fact] - public void SetsNothing_GivenNoPostProcessingAction() - { - var spec = new StoreEmptySpec(); + var spec = new StoreEmptySpec(); - spec.PostProcessingAction.Should().BeNull(); - } + spec.PostProcessingAction.Should().BeNull(); + } - [Fact] - public void SetsNothing_GivenSelectorSpecWithNoPostProcessingAction() - { - var spec = new StoreNamesEmptySpec(); + [Fact] + public void SetsNothing_GivenSelectorSpecWithNoPostProcessingAction() + { + var spec = new StoreNamesEmptySpec(); - spec.PostProcessingAction.Should().BeNull(); - } + spec.PostProcessingAction.Should().BeNull(); + } - [Fact] - public void SetsPostProcessingPredicate_GivenPostProcessingAction() - { - var spec = new StoreWithPostProcessingActionSpec(); + [Fact] + public void SetsPostProcessingPredicate_GivenPostProcessingAction() + { + var spec = new StoreWithPostProcessingActionSpec(); - spec.PostProcessingAction.Should().NotBeNull(); - } + spec.PostProcessingAction.Should().NotBeNull(); + } - [Fact] - public void SetsPostProcessingPredicate_GivenSelectorSpecWithPostProcessingAction() - { - var spec = new StoreNamesWithPostProcessingActionSpec(); + [Fact] + public void SetsPostProcessingPredicate_GivenSelectorSpecWithPostProcessingAction() + { + var spec = new StoreNamesWithPostProcessingActionSpec(); - spec.PostProcessingAction.Should().NotBeNull(); - } + spec.PostProcessingAction.Should().NotBeNull(); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Search.cs b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Search.cs index be6a3492..f32c2f08 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Search.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Search.cs @@ -1,65 +1,55 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Ardalis.Specification.UnitTests.Fixture.Entities; -using Ardalis.Specification.UnitTests.Fixture.Specs; -using FluentAssertions; -using Xunit; +namespace Ardalis.Specification.UnitTests; -namespace Ardalis.Specification.UnitTests +public class SpecificationBuilderExtensions_Search { - public class SpecificationBuilderExtensions_Search + [Fact] + public void AddsNothingToList_GivenNoWhereExpression() { - [Fact] - public void AddsNothingToList_GivenNoWhereExpression() - { - var spec = new StoreEmptySpec(); + var spec = new StoreEmptySpec(); - spec.SearchCriterias.Should().BeEmpty(); - } + spec.SearchCriterias.Should().BeEmpty(); + } - [Fact] - public void AddsNothingToList_GivenSearchExpressionWithFalseCondition() - { - var spec = new CompanyByIdWithFalseConditions(1); + [Fact] + public void AddsNothingToList_GivenSearchExpressionWithFalseCondition() + { + var spec = new CompanyByIdWithFalseConditions(1); - spec.SearchCriterias.Should().BeEmpty(); - } + spec.SearchCriterias.Should().BeEmpty(); + } - [Fact] - public void AddsOneCriteriaWithDefaultGroupToList_GivenOneSearchExpressionWithNoGroup() - { - var spec = new StoreSearchByNameSpec("test"); + [Fact] + public void AddsOneCriteriaWithDefaultGroupToList_GivenOneSearchExpressionWithNoGroup() + { + var spec = new StoreSearchByNameSpec("test"); - spec.SearchCriterias.Should().ContainSingle(); - spec.SearchCriterias.Single().SearchTerm.Should().Be("%test%"); - spec.SearchCriterias.Single().SearchGroup.Should().Be(1); - } + spec.SearchCriterias.Should().ContainSingle(); + spec.SearchCriterias.Single().SearchTerm.Should().Be("%test%"); + spec.SearchCriterias.Single().SearchGroup.Should().Be(1); + } - [Fact] - public void AddsTwoCriteriaWithSameGroupToList_GivenTwoSearchExpressionWithNoGroup() - { - var spec = new StoreSearchByNameOrCitySpec("test"); + [Fact] + public void AddsTwoCriteriaWithSameGroupToList_GivenTwoSearchExpressionWithNoGroup() + { + var spec = new StoreSearchByNameOrCitySpec("test"); - var criterias = spec.SearchCriterias.ToList(); + var criterias = spec.SearchCriterias.ToList(); - criterias.Should().HaveCount(2); - criterias.ForEach(x => x.SearchTerm.Should().Be("%test%")); - criterias.ForEach(x => x.SearchGroup.Should().Be(1)); - } + criterias.Should().HaveCount(2); + criterias.ForEach(x => x.SearchTerm.Should().Be("%test%")); + criterias.ForEach(x => x.SearchGroup.Should().Be(1)); + } - [Fact] - public void AddsTwoCriteriaWithDifferentGroupToList_GivenTwoSearchExpressionWithDistinctGroup() - { - var spec = new StoreSearchByNameAndCitySpec("test"); + [Fact] + public void AddsTwoCriteriaWithDifferentGroupToList_GivenTwoSearchExpressionWithDistinctGroup() + { + var spec = new StoreSearchByNameAndCitySpec("test"); - var criterias = spec.SearchCriterias.ToList(); + var criterias = spec.SearchCriterias.ToList(); - criterias.Should().HaveCount(2); - criterias.ForEach(x => x.SearchTerm.Should().Be("%test%")); - criterias[0].SearchGroup.Should().Be(1); - criterias[1].SearchGroup.Should().Be(2); - } + criterias.Should().HaveCount(2); + criterias.ForEach(x => x.SearchTerm.Should().Be("%test%")); + criterias[0].SearchGroup.Should().Be(1); + criterias[1].SearchGroup.Should().Be(2); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Select.cs b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Select.cs index b23e3028..f11dae26 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Select.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Select.cs @@ -1,30 +1,20 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Ardalis.Specification.UnitTests.Fixture.Entities; -using Ardalis.Specification.UnitTests.Fixture.Specs; -using FluentAssertions; -using Xunit; +namespace Ardalis.Specification.UnitTests; -namespace Ardalis.Specification.UnitTests +public class SpecificationBuilderExtensions_Select { - public class SpecificationBuilderExtensions_Select + [Fact] + public void SetsNothing_GivenNoSelectExpression() { - [Fact] - public void SetsNothing_GivenNoSelectExpression() - { - var spec = new StoreNamesEmptySpec(); + var spec = new StoreNamesEmptySpec(); - spec.Selector.Should().BeNull(); - } + spec.Selector.Should().BeNull(); + } - [Fact] - public void SetsSelector_GivenSelectExpression() - { - var spec = new StoreNamesSpec(); + [Fact] + public void SetsSelector_GivenSelectExpression() + { + var spec = new StoreNamesSpec(); - spec.Selector.Should().NotBeNull(); - } + spec.Selector.Should().NotBeNull(); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_SelectMany.cs b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_SelectMany.cs index f3c714f3..01f78d0e 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_SelectMany.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_SelectMany.cs @@ -1,25 +1,20 @@ -using Ardalis.Specification.UnitTests.Fixture.Specs; -using FluentAssertions; -using Xunit; +namespace Ardalis.Specification.UnitTests; -namespace Ardalis.Specification.UnitTests +public class SpecificationBuilderExtensions_SelectMany { - public class SpecificationBuilderExtensions_SelectMany + [Fact] + public void SetsNothing_GivenNoSelectManyExpression() { - [Fact] - public void SetsNothing_GivenNoSelectManyExpression() - { - var spec = new StoreProductNamesEmptySpec(); + var spec = new StoreProductNamesEmptySpec(); - spec.SelectorMany.Should().BeNull(); - } + spec.SelectorMany.Should().BeNull(); + } - [Fact] - public void SetsSelectorMany_GivenSelectManyExpression() - { - var spec = new StoreProductNamesSpec(); + [Fact] + public void SetsSelectorMany_GivenSelectManyExpression() + { + var spec = new StoreProductNamesSpec(); - spec.SelectorMany.Should().NotBeNull(); - } + spec.SelectorMany.Should().NotBeNull(); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Skip.cs b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Skip.cs index 9a1ceea4..eba5d262 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Skip.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Skip.cs @@ -1,39 +1,35 @@ using System; -using Ardalis.Specification.UnitTests.Fixture.Specs; -using FluentAssertions; -using Xunit; -namespace Ardalis.Specification.UnitTests +namespace Ardalis.Specification.UnitTests; + +public class SpecificationBuilderExtensions_Skip { - public class SpecificationBuilderExtensions_Skip + [Fact] + public void SetsSkipProperty_GivenValue() + { + var skip = 1; + + var spec = new StoreNamesPaginatedSpec(skip, 10); + + spec.Skip.Should() + .Be(skip); + } + + [Fact] + public void DoesNothing_GivenSkipWithFalseCondition() { - [Fact] - public void SetsSkipProperty_GivenValue() - { - var skip = 1; - - var spec = new StoreNamesPaginatedSpec(skip, 10); - - spec.Skip.Should() - .Be(skip); - } - - [Fact] - public void DoesNothing_GivenSkipWithFalseCondition() - { - var spec = new CompanyByIdWithFalseConditions(1); - - spec.Skip.Should().BeNull(); - } - - [Fact] - public void ThrowsDuplicateSkipException_GivenSkipUsedMoreThanOnce() - { - Action sutAction = () => new StoreDuplicateSkipSpec(); - - sutAction.Should() - .Throw() - .WithMessage("Duplicate use of Skip(). Ensure you don't use Skip() more than once in the same specification!"); - } + var spec = new CompanyByIdWithFalseConditions(1); + + spec.Skip.Should().BeNull(); + } + + [Fact] + public void ThrowsDuplicateSkipException_GivenSkipUsedMoreThanOnce() + { + Action sutAction = () => new StoreDuplicateSkipSpec(); + + sutAction.Should() + .Throw() + .WithMessage("Duplicate use of Skip(). Ensure you don't use Skip() more than once in the same specification!"); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Take.cs b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Take.cs index 4e238011..ab65ee14 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Take.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Take.cs @@ -1,37 +1,33 @@ using System; -using Ardalis.Specification.UnitTests.Fixture.Specs; -using FluentAssertions; -using Xunit; -namespace Ardalis.Specification.UnitTests +namespace Ardalis.Specification.UnitTests; + +public class SpecificationBuilderExtensions_Take { - public class SpecificationBuilderExtensions_Take + [Fact] + public void SetsTakeProperty_GivenValue() { - [Fact] - public void SetsTakeProperty_GivenValue() - { - var take = 10; - var spec = new StoreNamesPaginatedSpec(0, take); + var take = 10; + var spec = new StoreNamesPaginatedSpec(0, take); - spec.Take.Should().Be(take); - } + spec.Take.Should().Be(take); + } - [Fact] - public void DoesNothing_GivenTakeWithFalseCondition() - { - var spec = new CompanyByIdWithFalseConditions(1); + [Fact] + public void DoesNothing_GivenTakeWithFalseCondition() + { + var spec = new CompanyByIdWithFalseConditions(1); - spec.Take.Should().BeNull(); - } + spec.Take.Should().BeNull(); + } - [Fact] - public void ThrowsDuplicateTakeException_GivenTakeUsedMoreThanOnce() - { - Action sutAction = () => new StoreDuplicateTakeSpec(); + [Fact] + public void ThrowsDuplicateTakeException_GivenTakeUsedMoreThanOnce() + { + Action sutAction = () => new StoreDuplicateTakeSpec(); - sutAction.Should() - .Throw() - .WithMessage("Duplicate use of Take(). Ensure you don't use Take() more than once in the same specification!"); - } + sutAction.Should() + .Throw() + .WithMessage("Duplicate use of Take(). Ensure you don't use Take() more than once in the same specification!"); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Where.cs b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Where.cs index 97f3c64c..0623c456 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Where.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Where.cs @@ -1,46 +1,36 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Ardalis.Specification.UnitTests.Fixture.Entities; -using Ardalis.Specification.UnitTests.Fixture.Specs; -using FluentAssertions; -using Xunit; - -namespace Ardalis.Specification.UnitTests +namespace Ardalis.Specification.UnitTests; + +public class SpecificationBuilderExtensions_Where { - public class SpecificationBuilderExtensions_Where + [Fact] + public void AddsNothingToList_GivenNoWhereExpression() { - [Fact] - public void AddsNothingToList_GivenNoWhereExpression() - { - var spec = new StoreEmptySpec(); + var spec = new StoreEmptySpec(); - spec.WhereExpressions.Should().BeEmpty(); - } + spec.WhereExpressions.Should().BeEmpty(); + } - [Fact] - public void AddsNothingToList_GivenWhereExpressionWithFalseCondition() - { - var spec = new CompanyByIdWithFalseConditions(1); + [Fact] + public void AddsNothingToList_GivenWhereExpressionWithFalseCondition() + { + var spec = new CompanyByIdWithFalseConditions(1); - spec.WhereExpressions.Should().BeEmpty(); - } + spec.WhereExpressions.Should().BeEmpty(); + } - [Fact] - public void AddsOneExpressionToList_GivenOneWhereExpression() - { - var spec = new StoreByIdSpec(1); + [Fact] + public void AddsOneExpressionToList_GivenOneWhereExpression() + { + var spec = new StoreByIdSpec(1); - spec.WhereExpressions.Should().ContainSingle(); - } + spec.WhereExpressions.Should().ContainSingle(); + } - [Fact] - public void AddsTwoExpressionsToList_GivenTwoWhereExpressions() - { - var spec = new StoreByIdAndNameSpec(1, "name"); + [Fact] + public void AddsTwoExpressionsToList_GivenTwoWhereExpressions() + { + var spec = new StoreByIdAndNameSpec(1, "name"); - spec.WhereExpressions.Should().HaveCount(2); - } + spec.WhereExpressions.Should().HaveCount(2); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/EvaluatorTests/InMemorySpecificationEvaluatorTests.cs b/Specification/tests/Ardalis.Specification.UnitTests/EvaluatorTests/InMemorySpecificationEvaluatorTests.cs index e518f0fe..357f07e2 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/EvaluatorTests/InMemorySpecificationEvaluatorTests.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/EvaluatorTests/InMemorySpecificationEvaluatorTests.cs @@ -1,156 +1,146 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Ardalis.Specification.UnitTests.Fixture; -using Ardalis.Specification.UnitTests.Fixture.Entities; -using Ardalis.Specification.UnitTests.Fixture.Entities.Seeds; -using Ardalis.Specification.UnitTests.Fixture.Specs; -using FluentAssertions; -using Xunit; - -namespace Ardalis.Specification.UnitTests +using Ardalis.Specification.UnitTests.Fixture.Entities.Seeds; +using System; + +namespace Ardalis.Specification.UnitTests; + +public class InMemorySpecificationEvaluatorTests { - public class InMemorySpecificationEvaluatorTests + [Fact] + public void ReturnsStoreWithId10_GivenStoreByIdSpec() { - [Fact] - public void ReturnsStoreWithId10_GivenStoreByIdSpec() - { - var spec = new StoreByIdSpec(10); + var spec = new StoreByIdSpec(10); - var store = spec.Evaluate(StoreSeed.Get()).FirstOrDefault(); + var store = spec.Evaluate(StoreSeed.Get()).FirstOrDefault(); - store?.Id.Should().Be(10); - } + store?.Id.Should().Be(10); + } - [Fact] - public void ReturnsStoreWithIdFrom15To30_GivenStoresByIdListSpec() - { - var ids = Enumerable.Range(15, 16); - var spec = new StoresByIdListSpec(ids); + [Fact] + public void ReturnsStoreWithIdFrom15To30_GivenStoresByIdListSpec() + { + var ids = Enumerable.Range(15, 16); + var spec = new StoresByIdListSpec(ids); - var stores = spec.Evaluate(StoreSeed.Get()); + var stores = spec.Evaluate(StoreSeed.Get()); - stores.Count().Should().Be(16); - stores.OrderBy(x => x.Id).First().Id.Should().Be(15); - stores.OrderBy(x => x.Id).Last().Id.Should().Be(30); - } + stores.Count().Should().Be(16); + stores.OrderBy(x => x.Id).First().Id.Should().Be(15); + stores.OrderBy(x => x.Id).Last().Id.Should().Be(30); + } - [Fact] - public void ReturnsSecondPageOfStoreNames_GivenStoreNamesPaginatedSpec() - { - int take = 10; // pagesize 10 - int skip = (2 - 1) * 10; // page 2 + [Fact] + public void ReturnsSecondPageOfStoreNames_GivenStoreNamesPaginatedSpec() + { + var take = 10; // pagesize 10 + var skip = (2 - 1) * 10; // page 2 - var spec = new StoreNamesPaginatedSpec(skip, take); + var spec = new StoreNamesPaginatedSpec(skip, take); - var storeNames = spec.Evaluate(StoreSeed.Get()); + var storeNames = spec.Evaluate(StoreSeed.Get()); - storeNames.Count().Should().Be(take); - storeNames.First().Should().Be("Store 11"); - storeNames.Last().Should().Be("Store 20"); - } + storeNames.Count().Should().Be(take); + storeNames.First().Should().Be("Store 11"); + storeNames.Last().Should().Be("Store 20"); + } - [Fact] - public void ReturnsSecondPageOfStores_GivenStoresPaginatedSpec() - { - int take = 10; // pagesize 10 - int skip = (2 - 1) * 10; // page 2 + [Fact] + public void ReturnsSecondPageOfStores_GivenStoresPaginatedSpec() + { + var take = 10; // pagesize 10 + var skip = (2 - 1) * 10; // page 2 - var spec = new StoresPaginatedSpec(skip, take); + var spec = new StoresPaginatedSpec(skip, take); - var stores = spec.Evaluate(StoreSeed.Get()); + var stores = spec.Evaluate(StoreSeed.Get()); - stores.Count().Should().Be(take); - stores.OrderBy(x => x.Id).First().Id.Should().Be(11); - stores.OrderBy(x => x.Id).Last().Id.Should().Be(20); - } + stores.Count().Should().Be(take); + stores.OrderBy(x => x.Id).First().Id.Should().Be(11); + stores.OrderBy(x => x.Id).Last().Id.Should().Be(20); + } - [Fact] - public void ReturnsOrderStoresByNameDescForCompanyWithId2_GivenStoresByCompanyOrderedDescByNameSpec() - { - var spec = new StoresByCompanyOrderedDescByNameSpec(2); + [Fact] + public void ReturnsOrderStoresByNameDescForCompanyWithId2_GivenStoresByCompanyOrderedDescByNameSpec() + { + var spec = new StoresByCompanyOrderedDescByNameSpec(2); - var stores = spec.Evaluate(StoreSeed.Get()); + var stores = spec.Evaluate(StoreSeed.Get()); - stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_FIRST_ID); - stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_LAST_ID); - } + stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_FIRST_ID); + stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_LAST_ID); + } - [Fact] - public void ReturnsOrderStoresByNameDescThenByIdForCompanyWithId2_GivenStoresByCompanyOrderedDescByNameThenByIdSpec() - { - var spec = new StoresByCompanyOrderedDescByNameThenByIdSpec(2); + [Fact] + public void ReturnsOrderStoresByNameDescThenByIdForCompanyWithId2_GivenStoresByCompanyOrderedDescByNameThenByIdSpec() + { + var spec = new StoresByCompanyOrderedDescByNameThenByIdSpec(2); - var stores = spec.Evaluate(StoreSeed.Get()); + var stores = spec.Evaluate(StoreSeed.Get()); - stores.First().Id.Should().Be(99); - stores.Last().Id.Should().Be(98); - } + stores.First().Id.Should().Be(99); + stores.Last().Id.Should().Be(98); + } - [Fact] - public void ReturnsSecondPageOfStoresForCompanyWithId2_GivenStoresByCompanyPaginatedOrderedDescByNameSpec() - { - int take = 10; // pagesize 10 - int skip = (2 - 1) * 10; // page 2 + [Fact] + public void ReturnsSecondPageOfStoresForCompanyWithId2_GivenStoresByCompanyPaginatedOrderedDescByNameSpec() + { + var take = 10; // pagesize 10 + var skip = (2 - 1) * 10; // page 2 - var spec = new StoresByCompanyPaginatedOrderedDescByNameSpec(2, skip, take); + var spec = new StoresByCompanyPaginatedOrderedDescByNameSpec(2, skip, take); - var stores = spec.Evaluate(StoreSeed.Get()); + var stores = spec.Evaluate(StoreSeed.Get()); - stores.Count().Should().Be(take); - stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_PAGE2_FIRST_ID); - stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_PAGE2_LAST_ID); - } + stores.Count().Should().Be(take); + stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_PAGE2_FIRST_ID); + stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_PAGE2_LAST_ID); + } - [Fact] - public void ReturnsSecondPageOfStoresForCompanyWithId2_GivenStoresByCompanyPaginatedSpec() - { - int take = 10; // pagesize 10 - int skip = (2 - 1) * 10; // page 2 + [Fact] + public void ReturnsSecondPageOfStoresForCompanyWithId2_GivenStoresByCompanyPaginatedSpec() + { + var take = 10; // pagesize 10 + var skip = (2 - 1) * 10; // page 2 - var spec = new StoresByCompanyPaginatedSpec(2, skip, take); + var spec = new StoresByCompanyPaginatedSpec(2, skip, take); - var stores = spec.Evaluate(StoreSeed.Get()); + var stores = spec.Evaluate(StoreSeed.Get()); - stores.Count().Should().Be(take); - stores.OrderBy(x => x.Id).First().Id.Should().Be(61); - stores.OrderBy(x => x.Id).Last().Id.Should().Be(70); - } + stores.Count().Should().Be(take); + stores.OrderBy(x => x.Id).First().Id.Should().Be(61); + stores.OrderBy(x => x.Id).Last().Id.Should().Be(70); + } - [Fact] - public void ReturnsOrderedStores_GivenStoresOrderedSpecByName() - { - var spec = new StoresOrderedSpecByName(); + [Fact] + public void ReturnsOrderedStores_GivenStoresOrderedSpecByName() + { + var spec = new StoresOrderedSpecByName(); - var stores = spec.Evaluate(StoreSeed.Get()); + var stores = spec.Evaluate(StoreSeed.Get()); - stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_FIRST_ID); - stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_LAST_ID); - } + stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_FIRST_ID); + stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_LAST_ID); + } - [Fact] - public void ReturnsOrderedStores_GivenStoresOrderedDescendingByNameSpec() - { - var spec = new StoresOrderedDescendingByNameSpec(); + [Fact] + public void ReturnsOrderedStores_GivenStoresOrderedDescendingByNameSpec() + { + var spec = new StoresOrderedDescendingByNameSpec(); - var stores = spec.Evaluate(StoreSeed.Get()); + var stores = spec.Evaluate(StoreSeed.Get()); - stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FIRST_ID); - stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_LAST_ID); - } + stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FIRST_ID); + stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_LAST_ID); + } - [Fact] - public void ThrowsDuplicateOrderChainException_GivenSpecWithMultipleOrderChains() - { - var spec = new StoresOrderedTwoChainsSpec(); + [Fact] + public void ThrowsDuplicateOrderChainException_GivenSpecWithMultipleOrderChains() + { + var spec = new StoresOrderedTwoChainsSpec(); - Action sutAction = () => spec.Evaluate(StoreSeed.Get()); + Action sutAction = () => spec.Evaluate(StoreSeed.Get()); - sutAction.Should() - .Throw() - .WithMessage("The specification contains more than one Order chain!"); - } + sutAction.Should() + .Throw() + .WithMessage("The specification contains more than one Order chain!"); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/EvaluatorTests/SearchEvaluator_Evaluate.cs b/Specification/tests/Ardalis.Specification.UnitTests/EvaluatorTests/SearchEvaluator_Evaluate.cs index 9760fc22..be03a5ad 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/EvaluatorTests/SearchEvaluator_Evaluate.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/EvaluatorTests/SearchEvaluator_Evaluate.cs @@ -1,55 +1,48 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using FluentAssertions; -using Xunit; +using System.Collections.Generic; -namespace Ardalis.Specification.UnitTests +namespace Ardalis.Specification.UnitTests; + +public class SearchEvaluator_Evaluate { - public class SearchEvaluator_Evaluate + private static readonly List _people = new() { - public static List Data = new List - { - new Person("James"), - new Person("Robert"), - new Person("Mary"), - new Person("Linda"), - new Person("Michael"), - new Person("David"), - }; + new Person("James"), + new Person("Robert"), + new Person("Mary"), + new Person("Linda"), + new Person("Michael"), + new Person("David"), + }; - [Theory] - [InlineData("%mes", 1)] - [InlineData("%r%", 2)] - [InlineData("_inda", 1)] - [InlineData("M%", 2)] - [InlineData("[RM]%", 3)] - [InlineData("_[IA]%", 5)] - public void ReturnsFilteredList_GivenSearchExpression(string searchTerm, int expectedCount) - { - var result = SearchEvaluator.Instance.Evaluate(Data, new PersonSpecification(searchTerm)); + [Theory] + [InlineData("%mes", 1)] + [InlineData("%r%", 2)] + [InlineData("_inda", 1)] + [InlineData("M%", 2)] + [InlineData("[RM]%", 3)] + [InlineData("_[IA]%", 5)] + public void ReturnsFilteredList_GivenSearchExpression(string searchTerm, int expectedCount) + { + var result = SearchEvaluator.Instance.Evaluate(_people, new PersonSpecification(searchTerm)); - result.Should().HaveCount(expectedCount); - } + result.Should().HaveCount(expectedCount); } +} - public class PersonSpecification : Specification +public class PersonSpecification : Specification +{ + public PersonSpecification(string searchTerm) { - public PersonSpecification(string searchTerm) - { - Query.Search(x => x.Name, searchTerm); - } + Query.Search(x => x.Name, searchTerm); } +} - public class Person - { - public string Name { get; } +public class Person +{ + public string Name { get; } - public Person(string name) - { - Name = name; - } + public Person(string name) + { + Name = name; } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/EvaluatorTests/SearchExtension_Like.cs b/Specification/tests/Ardalis.Specification.UnitTests/EvaluatorTests/SearchExtension_Like.cs index 137389d7..8162ed58 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/EvaluatorTests/SearchExtension_Like.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/EvaluatorTests/SearchExtension_Like.cs @@ -1,98 +1,91 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using FluentAssertions; -using Xunit; -namespace Ardalis.Specification.UnitTests.EvaluatorTests +namespace Ardalis.Specification.UnitTests.EvaluatorTests; + +public class SearchExtension_Like { - public class SearchExtension_Like + [Theory] + [InlineData(true, "%", "")] + [InlineData(true, "%", " ")] + [InlineData(true, "%", "asdfa asdf asdf")] + [InlineData(true, "%", "%")] + [InlineData(false, "_", "")] + [InlineData(true, "_", " ")] + [InlineData(true, "_", "4")] + [InlineData(true, "_", "C")] + [InlineData(true, "_", "c")] + [InlineData(false, "_", "CX")] + [InlineData(false, "_", "cx")] + [InlineData(true, "[A]", "a")] + [InlineData(false, "[A]", "ab")] + [InlineData(false, "[ABCD]", "")] + [InlineData(true, "[ABCD]", "A")] + [InlineData(true, "[ABCD]", "b")] + [InlineData(false, "[ABCD]", "X")] + [InlineData(false, "[ABCD]", "AB")] + [InlineData(true, "[B-D]", "C")] + [InlineData(true, "[B-D]", "D")] + [InlineData(false, "[B-D]", "A")] + [InlineData(false, "[^B-D]", "C")] + [InlineData(false, "[^B-D]", "D")] + [InlineData(true, "[^B-D)]", "A")] + [InlineData(true, "%TEST[ABCD]XXX", "lolTESTBXXX")] + [InlineData(false, "%TEST[ABCD]XXX", "lolTESTZXXX")] + [InlineData(false, "%TEST[^ABCD]XXX", "lolTESTBXXX")] + [InlineData(true, "%TEST[^ABCD]XXX", "lolTESTZXXX")] + [InlineData(true, "%TEST[B-D]XXX", "lolTESTBXXX")] + [InlineData(true, "%TEST[^B-D)]XXX", "lolTESTZXXX")] + [InlineData(true, "%Stuff.txt", "Stuff.txt")] + [InlineData(true, "%Stuff.txt", "MagicStuff.txt")] + [InlineData(false, "%Stuff.txt", "MagicStuff.txt.img")] + [InlineData(false, "%Stuff.txt", "Stuff.txt.img")] + [InlineData(false, "%Stuff.txt", "MagicStuff001.txt.img")] + [InlineData(true, "Stuff.txt%", "Stuff.txt")] + [InlineData(false, "Stuff.txt%", "MagicStuff.txt")] + [InlineData(false, "Stuff.txt%", "MagicStuff.txt.img")] + [InlineData(true, "Stuff.txt%", "Stuff.txt.img")] + [InlineData(false, "Stuff.txt%", "MagicStuff001.txt.img")] + [InlineData(true, "%Stuff.txt%", "Stuff.txt")] + [InlineData(true, "%Stuff.txt%", "MagicStuff.txt")] + [InlineData(true, "%Stuff.txt%", "MagicStuff.txt.img")] + [InlineData(true, "%Stuff.txt%", "Stuff.txt.img")] + [InlineData(false, "%Stuff.txt%", "MagicStuff001.txt.img")] + [InlineData(true, "%Stuff%.txt", "Stuff.txt")] + [InlineData(true, "%Stuff%.txt", "MagicStuff.txt")] + [InlineData(false, "%Stuff%.txt", "MagicStuff.txt.img")] + [InlineData(false, "%Stuff%.txt", "Stuff.txt.img")] + [InlineData(false, "%Stuff%.txt", "MagicStuff001.txt.img")] + [InlineData(true, "%Stuff%.txt", "MagicStuff001.txt")] + [InlineData(true, "Stuff%.txt%", "Stuff.txt")] + [InlineData(false, "Stuff%.txt%", "MagicStuff.txt")] + [InlineData(false, "Stuff%.txt%", "MagicStuff.txt.img")] + [InlineData(true, "Stuff%.txt%", "Stuff.txt.img")] + [InlineData(false, "Stuff%.txt%", "MagicStuff001.txt.img")] + [InlineData(false, "Stuff%.txt%", "MagicStuff001.txt")] + [InlineData(true, "%Stuff%.txt%", "Stuff.txt")] + [InlineData(true, "%Stuff%.txt%", "MagicStuff.txt")] + [InlineData(true, "%Stuff%.txt%", "MagicStuff.txt.img")] + [InlineData(true, "%Stuff%.txt%", "Stuff.txt.img")] + [InlineData(true, "%Stuff%.txt%", "MagicStuff001.txt.img")] + [InlineData(true, "%Stuff%.txt%", "MagicStuff001.txt")] + [InlineData(true, "_Stuff_.txt_", "1Stuff3.txt4")] + [InlineData(false, "_Stuff_.txt_", "1Stuff.txt4")] + [InlineData(false, "_Stuff_.txt_", "1Stuff3.txt")] + [InlineData(false, "_Stuff_.txt_", "Stuff3.txt4")] + public void ReturnsExpectedResult_GivenPatternAndInput(bool expectedResult, string pattern, string input) { - [Theory] - [InlineData(true, "%", "")] - [InlineData(true, "%", " ")] - [InlineData(true, "%", "asdfa asdf asdf")] - [InlineData(true, "%", "%")] - [InlineData(false, "_", "")] - [InlineData(true, "_", " ")] - [InlineData(true, "_", "4")] - [InlineData(true, "_", "C")] - [InlineData(true, "_", "c")] - [InlineData(false, "_", "CX")] - [InlineData(false, "_", "cx")] - [InlineData(true, "[A]", "a")] - [InlineData(false, "[A]", "ab")] - [InlineData(false, "[ABCD]", "")] - [InlineData(true, "[ABCD]", "A")] - [InlineData(true, "[ABCD]", "b")] - [InlineData(false, "[ABCD]", "X")] - [InlineData(false, "[ABCD]", "AB")] - [InlineData(true, "[B-D]", "C")] - [InlineData(true, "[B-D]", "D")] - [InlineData(false, "[B-D]", "A")] - [InlineData(false, "[^B-D]", "C")] - [InlineData(false, "[^B-D]", "D")] - [InlineData(true, "[^B-D)]", "A")] - [InlineData(true, "%TEST[ABCD]XXX", "lolTESTBXXX")] - [InlineData(false, "%TEST[ABCD]XXX", "lolTESTZXXX")] - [InlineData(false, "%TEST[^ABCD]XXX", "lolTESTBXXX")] - [InlineData(true, "%TEST[^ABCD]XXX", "lolTESTZXXX")] - [InlineData(true, "%TEST[B-D]XXX", "lolTESTBXXX")] - [InlineData(true, "%TEST[^B-D)]XXX", "lolTESTZXXX")] - [InlineData(true, "%Stuff.txt", "Stuff.txt")] - [InlineData(true, "%Stuff.txt", "MagicStuff.txt")] - [InlineData(false, "%Stuff.txt", "MagicStuff.txt.img")] - [InlineData(false, "%Stuff.txt", "Stuff.txt.img")] - [InlineData(false, "%Stuff.txt", "MagicStuff001.txt.img")] - [InlineData(true, "Stuff.txt%", "Stuff.txt")] - [InlineData(false, "Stuff.txt%", "MagicStuff.txt")] - [InlineData(false, "Stuff.txt%", "MagicStuff.txt.img")] - [InlineData(true, "Stuff.txt%", "Stuff.txt.img")] - [InlineData(false, "Stuff.txt%", "MagicStuff001.txt.img")] - [InlineData(true, "%Stuff.txt%", "Stuff.txt")] - [InlineData(true, "%Stuff.txt%", "MagicStuff.txt")] - [InlineData(true, "%Stuff.txt%", "MagicStuff.txt.img")] - [InlineData(true, "%Stuff.txt%", "Stuff.txt.img")] - [InlineData(false, "%Stuff.txt%", "MagicStuff001.txt.img")] - [InlineData(true, "%Stuff%.txt", "Stuff.txt")] - [InlineData(true, "%Stuff%.txt", "MagicStuff.txt")] - [InlineData(false, "%Stuff%.txt", "MagicStuff.txt.img")] - [InlineData(false, "%Stuff%.txt", "Stuff.txt.img")] - [InlineData(false, "%Stuff%.txt", "MagicStuff001.txt.img")] - [InlineData(true, "%Stuff%.txt", "MagicStuff001.txt")] - [InlineData(true, "Stuff%.txt%", "Stuff.txt")] - [InlineData(false, "Stuff%.txt%", "MagicStuff.txt")] - [InlineData(false, "Stuff%.txt%", "MagicStuff.txt.img")] - [InlineData(true, "Stuff%.txt%", "Stuff.txt.img")] - [InlineData(false, "Stuff%.txt%", "MagicStuff001.txt.img")] - [InlineData(false, "Stuff%.txt%", "MagicStuff001.txt")] - [InlineData(true, "%Stuff%.txt%", "Stuff.txt")] - [InlineData(true, "%Stuff%.txt%", "MagicStuff.txt")] - [InlineData(true, "%Stuff%.txt%", "MagicStuff.txt.img")] - [InlineData(true, "%Stuff%.txt%", "Stuff.txt.img")] - [InlineData(true, "%Stuff%.txt%", "MagicStuff001.txt.img")] - [InlineData(true, "%Stuff%.txt%", "MagicStuff001.txt")] - [InlineData(true, "_Stuff_.txt_", "1Stuff3.txt4")] - [InlineData(false, "_Stuff_.txt_", "1Stuff.txt4")] - [InlineData(false, "_Stuff_.txt_", "1Stuff3.txt")] - [InlineData(false, "_Stuff_.txt_", "Stuff3.txt4")] - public void ReturnsExpectedResult_GivenPatternAndInput(bool expectedResult, string pattern, string input) - { - var result = input.Like(pattern); + var result = input.Like(pattern); - result.Should().Be(expectedResult); - } + result.Should().Be(expectedResult); + } - [Theory] - [InlineData("[", "asd")] - [InlineData("[]", "asd")] - public void ShouldThrowInvalidSearchPattern_GivenInvalidPattern(string pattern, string input) - { - Action action = () => input.Like(pattern); + [Theory] + [InlineData("[", "asd")] + [InlineData("[]", "asd")] + public void ShouldThrowInvalidSearchPattern_GivenInvalidPattern(string pattern, string input) + { + Action action = () => input.Like(pattern); - action.Should().Throw().WithMessage($"Invalid search pattern: {pattern}"); - } + action.Should().Throw().WithMessage($"Invalid search pattern: {pattern}"); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/ConcurrentSelectorsExceptionTests.cs b/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/ConcurrentSelectorsExceptionTests.cs index 86fa0067..c3bc6472 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/ConcurrentSelectorsExceptionTests.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/ConcurrentSelectorsExceptionTests.cs @@ -1,28 +1,25 @@ using System; -using FluentAssertions; -using Xunit; -namespace Ardalis.Specification.UnitTests +namespace Ardalis.Specification.UnitTests; + +public class ConcurrentSelectorsExceptionTests { - public class ConcurrentSelectorsExceptionTests - { - private const string defaultMessage = "Concurrent specification selector transforms defined. Ensure only one of the Select() or SelectMany() transforms is used in the same specification!"; + private const string _defaultMessage = "Concurrent specification selector transforms defined. Ensure only one of the Select() or SelectMany() transforms is used in the same specification!"; - [Fact] - public void ThrowWithDefaultConstructor() - { - Action action = () => throw new ConcurrentSelectorsException(); + [Fact] + public void ThrowWithDefaultConstructor() + { + Action action = () => throw new ConcurrentSelectorsException(); - action.Should().Throw().WithMessage(defaultMessage); - } + action.Should().Throw().WithMessage(_defaultMessage); + } - [Fact] - public void ThrowWithInnerException() - { - Exception inner = new Exception("test"); - Action action = () => throw new ConcurrentSelectorsException(inner); + [Fact] + public void ThrowWithInnerException() + { + var inner = new Exception("test"); + Action action = () => throw new ConcurrentSelectorsException(inner); - action.Should().Throw().WithMessage(defaultMessage).WithInnerException().WithMessage("test"); - } + action.Should().Throw().WithMessage(_defaultMessage).WithInnerException().WithMessage("test"); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/DuplicateOrderChainExceptionTests.cs b/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/DuplicateOrderChainExceptionTests.cs index ef5a30d3..f4294acb 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/DuplicateOrderChainExceptionTests.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/DuplicateOrderChainExceptionTests.cs @@ -1,30 +1,25 @@ using System; -using System.Collections.Generic; -using System.Text; -using FluentAssertions; -using Xunit; -namespace Ardalis.Specification.UnitTests +namespace Ardalis.Specification.UnitTests; + +public class DuplicateOrderChainExceptionTests { - public class DuplicateOrderChainExceptionTests - { - private const string defaultMessage = "The specification contains more than one Order chain!"; + private const string _defaultMessage = "The specification contains more than one Order chain!"; - [Fact] - public void ThrowWithDefaultConstructor() - { - Action action = () => throw new DuplicateOrderChainException(); + [Fact] + public void ThrowWithDefaultConstructor() + { + Action action = () => throw new DuplicateOrderChainException(); - action.Should().Throw().WithMessage(defaultMessage); - } + action.Should().Throw().WithMessage(_defaultMessage); + } - [Fact] - public void ThrowWithInnerException() - { - Exception inner = new Exception("test"); - Action action = () => throw new DuplicateOrderChainException(inner); + [Fact] + public void ThrowWithInnerException() + { + var inner = new Exception("test"); + Action action = () => throw new DuplicateOrderChainException(inner); - action.Should().Throw().WithMessage(defaultMessage).WithInnerException().WithMessage("test"); - } + action.Should().Throw().WithMessage(_defaultMessage).WithInnerException().WithMessage("test"); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/DuplicateSkipExceptionTests.cs b/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/DuplicateSkipExceptionTests.cs index 6d3f4c95..92477a85 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/DuplicateSkipExceptionTests.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/DuplicateSkipExceptionTests.cs @@ -1,30 +1,25 @@ using System; -using System.Collections.Generic; -using System.Text; -using FluentAssertions; -using Xunit; -namespace Ardalis.Specification.UnitTests +namespace Ardalis.Specification.UnitTests; + +public class DuplicateSkipExceptionTests { - public class DuplicateSkipExceptionTests - { - private const string defaultMessage = "Duplicate use of Skip(). Ensure you don't use Skip() more than once in the same specification!"; + private const string _defaultMessage = "Duplicate use of Skip(). Ensure you don't use Skip() more than once in the same specification!"; - [Fact] - public void ThrowWithDefaultConstructor() - { - Action action = () => throw new DuplicateSkipException(); + [Fact] + public void ThrowWithDefaultConstructor() + { + Action action = () => throw new DuplicateSkipException(); - action.Should().Throw().WithMessage(defaultMessage); - } + action.Should().Throw().WithMessage(_defaultMessage); + } - [Fact] - public void ThrowWithInnerException() - { - Exception inner = new Exception("test"); - Action action = () => throw new DuplicateSkipException(inner); + [Fact] + public void ThrowWithInnerException() + { + var inner = new Exception("test"); + Action action = () => throw new DuplicateSkipException(inner); - action.Should().Throw().WithMessage(defaultMessage).WithInnerException().WithMessage("test"); - } + action.Should().Throw().WithMessage(_defaultMessage).WithInnerException().WithMessage("test"); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/DuplicateTakeExceptionTests.cs b/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/DuplicateTakeExceptionTests.cs index 147646c8..fafebaab 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/DuplicateTakeExceptionTests.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/DuplicateTakeExceptionTests.cs @@ -1,30 +1,25 @@ using System; -using System.Collections.Generic; -using System.Text; -using FluentAssertions; -using Xunit; -namespace Ardalis.Specification.UnitTests +namespace Ardalis.Specification.UnitTests; + +public class DuplicateTakeExceptionTests { - public class DuplicateTakeExceptionTests - { - private const string defaultMessage = "Duplicate use of Take(). Ensure you don't use Take() more than once in the same specification!"; + private const string _defaultMessage = "Duplicate use of Take(). Ensure you don't use Take() more than once in the same specification!"; - [Fact] - public void ThrowWithDefaultConstructor() - { - Action action = () => throw new DuplicateTakeException(); + [Fact] + public void ThrowWithDefaultConstructor() + { + Action action = () => throw new DuplicateTakeException(); - action.Should().Throw().WithMessage(defaultMessage); - } + action.Should().Throw().WithMessage(_defaultMessage); + } - [Fact] - public void ThrowWithInnerException() - { - Exception inner = new Exception("test"); - Action action = () => throw new DuplicateTakeException(inner); + [Fact] + public void ThrowWithInnerException() + { + var inner = new Exception("test"); + Action action = () => throw new DuplicateTakeException(inner); - action.Should().Throw().WithMessage(defaultMessage).WithInnerException().WithMessage("test"); - } + action.Should().Throw().WithMessage(_defaultMessage).WithInnerException().WithMessage("test"); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/InvalidSearchPatternExceptionTests.cs b/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/InvalidSearchPatternExceptionTests.cs index 3c0fa1ff..3ca556a9 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/InvalidSearchPatternExceptionTests.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/InvalidSearchPatternExceptionTests.cs @@ -1,31 +1,26 @@ using System; -using System.Collections.Generic; -using System.Text; -using FluentAssertions; -using Xunit; -namespace Ardalis.Specification.UnitTests +namespace Ardalis.Specification.UnitTests; + +public class InvalidSearchPatternExceptionTests { - public class InvalidSearchPatternExceptionTests - { - private const string defaultMessage = "Invalid search pattern: " + pattern; - private const string pattern = "x"; + private const string _defaultMessage = "Invalid search pattern: " + _pattern; + private const string _pattern = "x"; - [Fact] - public void ThrowWithDefaultConstructor() - { - Action action = () => throw new InvalidSearchPatternException(pattern); + [Fact] + public void ThrowWithDefaultConstructor() + { + Action action = () => throw new InvalidSearchPatternException(_pattern); - action.Should().Throw(pattern).WithMessage(defaultMessage); - } + action.Should().Throw(_pattern).WithMessage(_defaultMessage); + } - [Fact] - public void ThrowWithInnerException() - { - Exception inner = new Exception("test"); - Action action = () => throw new InvalidSearchPatternException(pattern, inner); + [Fact] + public void ThrowWithInnerException() + { + var inner = new Exception("test"); + Action action = () => throw new InvalidSearchPatternException(_pattern, inner); - action.Should().Throw(pattern).WithMessage(defaultMessage).WithInnerException().WithMessage("test"); - } + action.Should().Throw(_pattern).WithMessage(_defaultMessage).WithInnerException().WithMessage("test"); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/SelectorNotFoundExceptionTests.cs b/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/SelectorNotFoundExceptionTests.cs index 4b54d141..72e9b39d 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/SelectorNotFoundExceptionTests.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/SelectorNotFoundExceptionTests.cs @@ -1,28 +1,25 @@ using System; -using FluentAssertions; -using Xunit; -namespace Ardalis.Specification.UnitTests +namespace Ardalis.Specification.UnitTests; + +public class SelectorNotFoundExceptionTests { - public class SelectorNotFoundExceptionTests - { - private const string defaultMessage = "The specification must have a selector transform defined. Ensure either Select() or SelectMany() is used in the specification!"; + private const string _defaultMessage = "The specification must have a selector transform defined. Ensure either Select() or SelectMany() is used in the specification!"; - [Fact] - public void ThrowWithDefaultConstructor() - { - Action action = () => throw new SelectorNotFoundException(); + [Fact] + public void ThrowWithDefaultConstructor() + { + Action action = () => throw new SelectorNotFoundException(); - action.Should().Throw().WithMessage(defaultMessage); - } + action.Should().Throw().WithMessage(_defaultMessage); + } - [Fact] - public void ThrowWithInnerException() - { - Exception inner = new Exception("test"); - Action action = () => throw new SelectorNotFoundException(inner); + [Fact] + public void ThrowWithInnerException() + { + var inner = new Exception("test"); + Action action = () => throw new SelectorNotFoundException(inner); - action.Should().Throw().WithMessage(defaultMessage).WithInnerException().WithMessage("test"); - } + action.Should().Throw().WithMessage(_defaultMessage).WithInnerException().WithMessage("test"); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Address.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Address.cs index 8018c28f..1b197d7c 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Address.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Address.cs @@ -1,20 +1,15 @@ -using System; -using System.Collections.Generic; -using System.Text; +namespace Ardalis.Specification.UnitTests.Fixture.Entities; -namespace Ardalis.Specification.UnitTests.Fixture.Entities +public class Address { - public class Address - { - public int Id { get; set; } - public string? Street { get; set; } + public int Id { get; set; } + public string? Street { get; set; } - public int StoreId { get; set; } - public Store? Store { get; set; } + public int StoreId { get; set; } + public Store? Store { get; set; } - public object GetSomethingFromAddress() - { - return new object(); - } + public object GetSomethingFromAddress() + { + return new object(); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Company.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Company.cs index ac748568..5b384393 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Company.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Company.cs @@ -1,17 +1,14 @@ -using System; -using System.Collections.Generic; -using System.Text; +using System.Collections.Generic; -namespace Ardalis.Specification.UnitTests.Fixture.Entities +namespace Ardalis.Specification.UnitTests.Fixture.Entities; + +public class Company { - public class Company - { - public int Id { get; set; } - public string? Name { get; set; } + public int Id { get; set; } + public string? Name { get; set; } - public int CountryId { get; set; } - public Country? Country { get; set; } + public int CountryId { get; set; } + public Country? Country { get; set; } - public List Stores { get; set; } = new List(); - } + public List Stores { get; set; } = new List(); } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Country.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Country.cs index 6fb115e9..2ec5b0c8 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Country.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Country.cs @@ -1,14 +1,11 @@ -using System; -using System.Collections.Generic; -using System.Text; +using System.Collections.Generic; -namespace Ardalis.Specification.UnitTests.Fixture.Entities +namespace Ardalis.Specification.UnitTests.Fixture.Entities; + +public class Country { - public class Country - { - public int Id { get; set; } - public string? Name { get; set; } + public int Id { get; set; } + public string? Name { get; set; } - public List Companies { get; set; } = new List(); - } + public List Companies { get; set; } = new List(); } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Product.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Product.cs index acda3ac9..e055b0b6 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Product.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Product.cs @@ -1,15 +1,10 @@ -using System; -using System.Collections.Generic; -using System.Text; +namespace Ardalis.Specification.UnitTests.Fixture.Entities; -namespace Ardalis.Specification.UnitTests.Fixture.Entities +public class Product { - public class Product - { - public int Id { get; set; } - public string? Name { get; set; } + public int Id { get; set; } + public string? Name { get; set; } - public int StoreId { get; set; } - public Store? Store { get; set; } - } + public int StoreId { get; set; } + public Store? Store { get; set; } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Seeds/AddressSeed.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Seeds/AddressSeed.cs index c82320ee..03a8e6ab 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Seeds/AddressSeed.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Seeds/AddressSeed.cs @@ -1,28 +1,27 @@ -using System; -using System.Collections.Generic; -using System.Text; +using System.Collections.Generic; -namespace Ardalis.Specification.UnitTests.Fixture.Entities.Seeds +namespace Ardalis.Specification.UnitTests.Fixture.Entities.Seeds; + +public class AddressSeed { - public class AddressSeed +#pragma warning disable IDE1006 // Naming Styles + public const string VALID_STREET_FOR_STOREID1 = "Street 1"; +#pragma warning restore IDE1006 // Naming Styles + + public static List
Get() { - public const string VALID_STREET_FOR_STOREID1 = "Street 1"; + var addresses = new List
(); - public static List
Get() + for (var i = 1; i <= 100; i++) { - var addresses = new List
(); - - for (int i = 1; i <= 100; i++) + addresses.Add(new Address() { - addresses.Add(new Address() - { - Id = i, - Street = $"Street {i}", - StoreId = i - }); - } - - return addresses; + Id = i, + Street = $"Street {i}", + StoreId = i + }); } + + return addresses; } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Seeds/CompanySeed.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Seeds/CompanySeed.cs index 69a91eab..c19853e7 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Seeds/CompanySeed.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Seeds/CompanySeed.cs @@ -1,40 +1,40 @@ -using System; -using System.Collections.Generic; -using System.Text; +using System.Collections.Generic; -namespace Ardalis.Specification.UnitTests.Fixture.Entities.Seeds +namespace Ardalis.Specification.UnitTests.Fixture.Entities.Seeds; + +public class CompanySeed { - public class CompanySeed - { - public const int VALID_COMPANY_ID = 1; - public const string VALID_COMPANY_NAME = "Company 1"; +#pragma warning disable IDE1006 // Naming Styles + public const int VALID_COMPANY_ID = 1; + public const string VALID_COMPANY_NAME = "Company 1"; +#pragma warning restore IDE1006 // Naming Styles - public static List Get() + public static List Get() + { + var companies = new List { - var companies = new List(); - - companies.Add(new Company() + new Company() { Id = 1, Name = "Company 1", CountryId = 1, - }); + }, - companies.Add(new Company() + new Company() { Id = 2, Name = "Company 2", CountryId = 2, - }); + }, - companies.Add(new Company() + new Company() { Id = 3, Name = "Company 3", CountryId = 1, - }); + } + }; - return companies; - } + return companies; } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Seeds/CountrySeed.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Seeds/CountrySeed.cs index aaf83868..f83c48c7 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Seeds/CountrySeed.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Seeds/CountrySeed.cs @@ -1,28 +1,25 @@ -using System; -using System.Collections.Generic; -using System.Text; +using System.Collections.Generic; -namespace Ardalis.Specification.UnitTests.Fixture.Entities.Seeds +namespace Ardalis.Specification.UnitTests.Fixture.Entities.Seeds; + +public class CountrySeed { - public class CountrySeed + public static List Get() { - public static List Get() - { - var countries = new List(); + var countries = new List(); - countries.Add(new Country() - { - Id = 1, - Name = "Country 1", - }); + countries.Add(new Country() + { + Id = 1, + Name = "Country 1", + }); - countries.Add(new Country() - { - Id = 2, - Name = "Country 2", - }); + countries.Add(new Country() + { + Id = 2, + Name = "Country 2", + }); - return countries; - } + return countries; } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Seeds/ProductSeed.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Seeds/ProductSeed.cs index ffef31c1..54b1a83d 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Seeds/ProductSeed.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Seeds/ProductSeed.cs @@ -1,33 +1,34 @@ using System.Collections.Generic; -namespace Ardalis.Specification.UnitTests.Fixture.Entities.Seeds +namespace Ardalis.Specification.UnitTests.Fixture.Entities.Seeds; + +public class ProductSeed { - public class ProductSeed +#pragma warning disable IDE1006 // Naming Styles + public const int TOTAL_PRODUCT_COUNT = 100; + public const string VALID_PRODUCT_NAME = "Product 1"; +#pragma warning restore IDE1006 // Naming Styles + + public static List Get() { - public const int TOTAL_PRODUCT_COUNT = 100; - public const string VALID_PRODUCT_NAME = "Product 1"; + var products = new List(); - public static List Get() + for (var i = 1; i < TOTAL_PRODUCT_COUNT; i += 2) { - var products = new List(); - - for (int i = 1; i < TOTAL_PRODUCT_COUNT; i = i + 2) + products.Add(new Product() { - products.Add(new Product() - { - Id = i, - Name = $"Product {i}", - StoreId = i, - }); - products.Add(new Product() - { - Id = i + 1, - Name = $"Product {i + 1}", - StoreId = i, - }); - } - - return products; + Id = i, + Name = $"Product {i}", + StoreId = i, + }); + products.Add(new Product() + { + Id = i + 1, + Name = $"Product {i + 1}", + StoreId = i, + }); } + + return products; } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Seeds/StoreSeed.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Seeds/StoreSeed.cs index 95429d9e..842f942b 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Seeds/StoreSeed.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Seeds/StoreSeed.cs @@ -1,77 +1,75 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; +using System.Collections.Generic; -namespace Ardalis.Specification.UnitTests.Fixture.Entities.Seeds +namespace Ardalis.Specification.UnitTests.Fixture.Entities.Seeds; + +public class StoreSeed { - public class StoreSeed - { - public const int VALID_STORE_ID = 1; - public const string VALID_STORE_NAME = "Store 1"; - public const string VALID_STORE_City = "City 1"; +#pragma warning disable IDE1006 // Naming Styles + public const int VALID_STORE_ID = 1; + public const string VALID_STORE_NAME = "Store 1"; + public const string VALID_STORE_City = "City 1"; - public const int VALID_Search_ID = 50; - public const string VALID_Search_City_Key = "BCD"; - public const string VALID_Search_Name_Key = "BCE"; - public const string VALID_Search_City_Name_Key = "BC"; + public const int VALID_Search_ID = 50; + public const string VALID_Search_City_Key = "BCD"; + public const string VALID_Search_Name_Key = "BCE"; + public const string VALID_Search_City_Name_Key = "BC"; - public const int ORDERED_BY_NAME_FIRST_ID = 48; - public const int ORDERED_BY_NAME_LAST_ID = 49; - public const int ORDERED_BY_NAME_DESC_FIRST_ID = 49; - public const int ORDERED_BY_NAME_DESC_LAST_ID = 48; + public const int ORDERED_BY_NAME_FIRST_ID = 48; + public const int ORDERED_BY_NAME_LAST_ID = 49; + public const int ORDERED_BY_NAME_DESC_FIRST_ID = 49; + public const int ORDERED_BY_NAME_DESC_LAST_ID = 48; - public const int ORDERED_BY_NAME_FOR_COMPANY2_FIRST_ID = 98; - public const int ORDERED_BY_NAME_FOR_COMPANY2_LAST_ID = 99; - public const int ORDERED_BY_NAME_DESC_FOR_COMPANY2_FIRST_ID = 99; - public const int ORDERED_BY_NAME_DESC_FOR_COMPANY2_LAST_ID = 98; - public const int ORDERED_BY_NAME_DESC_FOR_COMPANY2_PAGE2_FIRST_ID = 89; - public const int ORDERED_BY_NAME_DESC_FOR_COMPANY2_PAGE2_LAST_ID = 80; + public const int ORDERED_BY_NAME_FOR_COMPANY2_FIRST_ID = 98; + public const int ORDERED_BY_NAME_FOR_COMPANY2_LAST_ID = 99; + public const int ORDERED_BY_NAME_DESC_FOR_COMPANY2_FIRST_ID = 99; + public const int ORDERED_BY_NAME_DESC_FOR_COMPANY2_LAST_ID = 98; + public const int ORDERED_BY_NAME_DESC_FOR_COMPANY2_PAGE2_FIRST_ID = 89; + public const int ORDERED_BY_NAME_DESC_FOR_COMPANY2_PAGE2_LAST_ID = 80; +#pragma warning restore IDE1006 // Naming Styles - public static List Get() - { - var stores = new List(); + public static List Get() + { + var stores = new List(); - for (int i = 1; i <= 50; i++) + for (var i = 1; i <= 50; i++) + { + stores.Add(new Store() { - stores.Add(new Store() - { - Id = i, - Name = $"Store {i}", - City = $"City {i}", - AddressId = i, - CompanyId = 1, - }); - } - for (int i = 51; i <= 100; i++) + Id = i, + Name = $"Store {i}", + City = $"City {i}", + AddressId = i, + CompanyId = 1, + }); + } + for (var i = 51; i <= 100; i++) + { + stores.Add(new Store() { - stores.Add(new Store() - { - Id = i, - Name = $"Store {i}", - City = $"City {i}", - AddressId = i, - CompanyId = 2, - }); - } + Id = i, + Name = $"Store {i}", + City = $"City {i}", + AddressId = i, + CompanyId = 2, + }); + } - stores[49 - 1].Name = "ZZZ"; - stores[48 - 1].Name = "AAA"; - stores[99 - 1].Name = "YYY"; - stores[98 - 1].Name = "BBB"; + stores[49 - 1].Name = "ZZZ"; + stores[48 - 1].Name = "AAA"; + stores[99 - 1].Name = "YYY"; + stores[98 - 1].Name = "BBB"; - stores[100 - 1].Name = "Store 999"; + stores[100 - 1].Name = "Store 999"; - stores[50 - 1].City = "ABCDEFGH"; - stores[50 - 1].Name = "ABCEFGH"; + stores[50 - 1].City = "ABCDEFGH"; + stores[50 - 1].Name = "ABCEFGH"; - return stores; - } + return stores; + } - internal static IQueryable AsQueryable() - { - return Get().AsQueryable(); - } + internal static IQueryable AsQueryable() + { + return Get().AsQueryable(); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Store.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Store.cs index 6775a0eb..24373c4d 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Store.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Store.cs @@ -1,24 +1,23 @@ using System.Collections.Generic; -namespace Ardalis.Specification.UnitTests.Fixture.Entities +namespace Ardalis.Specification.UnitTests.Fixture.Entities; + +public class Store { - public class Store - { - public int Id { get; set; } - public string? Name { get; set; } - public string? City { get; set; } + public int Id { get; set; } + public string? Name { get; set; } + public string? City { get; set; } - public int CompanyId { get; set; } - public Company? Company { get; set; } + public int CompanyId { get; set; } + public Company? Company { get; set; } - public int AddressId { get; set; } - public Address? Address { get; set; } + public int AddressId { get; set; } + public Address? Address { get; set; } - public List Products { get; set; } = new List(); + public List Products { get; set; } = new List(); - public object GetSomethingFromStore() - { - return new object(); - } + public static object GetSomethingFromStore() + { + return new object(); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdAsSplitQuery.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdAsSplitQuery.cs index 142ff1cd..5b8b630e 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdAsSplitQuery.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdAsSplitQuery.cs @@ -1,15 +1,12 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class CompanyByIdAsSplitQuery : Specification, ISingleResultSpecification { - public class CompanyByIdAsSplitQuery : Specification, ISingleResultSpecification + public CompanyByIdAsSplitQuery(int id) { - public CompanyByIdAsSplitQuery(int id) - { - Query.Where(company => company.Id == id) - .Include(x => x.Stores) - .ThenInclude(x => x.Products) - .AsSplitQuery(); - } + Query.Where(company => company.Id == id) + .Include(x => x.Stores) + .ThenInclude(x => x.Products) + .AsSplitQuery(); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdAsTrackedSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdAsTrackedSpec.cs index 88efb470..e0914e95 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdAsTrackedSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdAsTrackedSpec.cs @@ -1,12 +1,9 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class CompanyByIdAsTrackedSpec : Specification, ISingleResultSpecification { - public class CompanyByIdAsTrackedSpec : Specification, ISingleResultSpecification + public CompanyByIdAsTrackedSpec(int id) { - public CompanyByIdAsTrackedSpec(int id) - { - Query.Where(company => company.Id == id).AsTracking(); - } + Query.Where(company => company.Id == id).AsTracking(); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdAsUntrackedSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdAsUntrackedSpec.cs index c927e1c1..5d884f6d 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdAsUntrackedSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdAsUntrackedSpec.cs @@ -1,12 +1,9 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class CompanyByIdAsUntrackedSpec : Specification, ISingleResultSpecification { - public class CompanyByIdAsUntrackedSpec : Specification, ISingleResultSpecification + public CompanyByIdAsUntrackedSpec(int id) { - public CompanyByIdAsUntrackedSpec(int id) - { - Query.Where(company => company.Id == id).AsNoTracking(); - } + Query.Where(company => company.Id == id).AsNoTracking(); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdAsUntrackedWithIdentityResolutionSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdAsUntrackedWithIdentityResolutionSpec.cs index 8da92f0e..39167e2e 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdAsUntrackedWithIdentityResolutionSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdAsUntrackedWithIdentityResolutionSpec.cs @@ -1,12 +1,9 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class CompanyByIdAsUntrackedWithIdentityResolutionSpec : Specification, ISingleResultSpecification { - public class CompanyByIdAsUntrackedWithIdentityResolutionSpec : Specification, ISingleResultSpecification + public CompanyByIdAsUntrackedWithIdentityResolutionSpec(int id) { - public CompanyByIdAsUntrackedWithIdentityResolutionSpec(int id) - { - Query.Where(company => company.Id == id).AsNoTrackingWithIdentityResolution(); - } + Query.Where(company => company.Id == id).AsNoTrackingWithIdentityResolution(); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdIgnoreQueryFilters.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdIgnoreQueryFilters.cs index 3514d637..bcc6b731 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdIgnoreQueryFilters.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdIgnoreQueryFilters.cs @@ -1,12 +1,9 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class CompanyByIdIgnoreQueryFilters : Specification, ISingleResultSpecification { - public class CompanyByIdIgnoreQueryFilters : Specification, ISingleResultSpecification + public CompanyByIdIgnoreQueryFilters(int id) { - public CompanyByIdIgnoreQueryFilters(int id) - { - Query.Where(company => company.Id == id).IgnoreQueryFilters(); - } + Query.Where(company => company.Id == id).IgnoreQueryFilters(); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdIncludeStoresThenIncludeAddressSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdIncludeStoresThenIncludeAddressSpec.cs index 2d655299..7f581b2f 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdIncludeStoresThenIncludeAddressSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdIncludeStoresThenIncludeAddressSpec.cs @@ -1,14 +1,11 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class CompanyByIdIncludeStoresThenIncludeAddressSpec : Specification, ISingleResultSpecification { - public class CompanyByIdIncludeStoresThenIncludeAddressSpec : Specification, ISingleResultSpecification + public CompanyByIdIncludeStoresThenIncludeAddressSpec(int id) { - public CompanyByIdIncludeStoresThenIncludeAddressSpec(int id) - { - Query.Where(x => x.Id == id) - .Include(x => x.Stores) - .ThenInclude(x => x.Address); - } + Query.Where(x => x.Id == id) + .Include(x => x.Stores) + .ThenInclude(x => x.Address); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdIncludeStoresThenIncludeProductsSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdIncludeStoresThenIncludeProductsSpec.cs index 85948f8b..03105a93 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdIncludeStoresThenIncludeProductsSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdIncludeStoresThenIncludeProductsSpec.cs @@ -1,14 +1,11 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class CompanyByIdIncludeStoresThenIncludeProductsSpec : Specification, ISingleResultSpecification { - public class CompanyByIdIncludeStoresThenIncludeProductsSpec : Specification, ISingleResultSpecification + public CompanyByIdIncludeStoresThenIncludeProductsSpec(int id) { - public CompanyByIdIncludeStoresThenIncludeProductsSpec(int id) - { - Query.Where(x => x.Id == id) - .Include(x => x.Stores) - .ThenInclude(x => x.Products); - } + Query.Where(x => x.Id == id) + .Include(x => x.Stores) + .ThenInclude(x => x.Products); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdSpec.cs index 9ffc3458..83339033 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdSpec.cs @@ -1,12 +1,9 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class CompanyByIdSpec : Specification, ISingleResultSpecification { - public class CompanyByIdSpec : Specification, ISingleResultSpecification + public CompanyByIdSpec(int id) { - public CompanyByIdSpec(int id) - { - Query.Where(company => company.Id == id); - } + Query.Where(company => company.Id == id); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdWithAsNoTrackingAsTrackedSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdWithAsNoTrackingAsTrackedSpec.cs index 342e3f59..79a46ea6 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdWithAsNoTrackingAsTrackedSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdWithAsNoTrackingAsTrackedSpec.cs @@ -1,12 +1,9 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class CompanyByIdWithAsNoTrackingAsTrackedSpec : Specification, ISingleResultSpecification { - public class CompanyByIdWithAsNoTrackingAsTrackedSpec : Specification, ISingleResultSpecification + public CompanyByIdWithAsNoTrackingAsTrackedSpec(int id) { - public CompanyByIdWithAsNoTrackingAsTrackedSpec(int id) - { - Query.Where(company => company.Id == id).AsNoTracking().AsNoTrackingWithIdentityResolution().AsTracking(); - } + Query.Where(company => company.Id == id).AsNoTracking().AsNoTrackingWithIdentityResolution().AsTracking(); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdWithAsTrackingAsUntrackedSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdWithAsTrackingAsUntrackedSpec.cs index 16201d6d..c7a5ca52 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdWithAsTrackingAsUntrackedSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdWithAsTrackingAsUntrackedSpec.cs @@ -1,12 +1,9 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class CompanyByIdWithAsTrackingAsUntrackedSpec : Specification, ISingleResultSpecification { - public class CompanyByIdWithAsTrackingAsUntrackedSpec : Specification, ISingleResultSpecification + public CompanyByIdWithAsTrackingAsUntrackedSpec(int id) { - public CompanyByIdWithAsTrackingAsUntrackedSpec(int id) - { - Query.Where(company => company.Id == id).AsTracking().AsNoTracking(); - } + Query.Where(company => company.Id == id).AsTracking().AsNoTracking(); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdWithAsTrackingAsUntrackedWithIdentityResolutionSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdWithAsTrackingAsUntrackedWithIdentityResolutionSpec.cs index f4fd1197..aeeebb7e 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdWithAsTrackingAsUntrackedWithIdentityResolutionSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdWithAsTrackingAsUntrackedWithIdentityResolutionSpec.cs @@ -1,13 +1,10 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class CompanyByIdWithAsTrackingAsUntrackedWithIdentityResolutionSpec : Specification, + ISingleResultSpecification { - public class CompanyByIdWithAsTrackingAsUntrackedWithIdentityResolutionSpec : Specification, - ISingleResultSpecification + public CompanyByIdWithAsTrackingAsUntrackedWithIdentityResolutionSpec(int id) { - public CompanyByIdWithAsTrackingAsUntrackedWithIdentityResolutionSpec(int id) - { - Query.Where(company => company.Id == id).AsTracking().AsNoTrackingWithIdentityResolution(); - } + Query.Where(company => company.Id == id).AsTracking().AsNoTrackingWithIdentityResolution(); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdWithFalseConditions.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdWithFalseConditions.cs index 3be772f7..b6a2a2d5 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdWithFalseConditions.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdWithFalseConditions.cs @@ -1,29 +1,26 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class CompanyByIdWithFalseConditions : Specification, ISingleResultSpecification { - public class CompanyByIdWithFalseConditions : Specification, ISingleResultSpecification + public CompanyByIdWithFalseConditions(int id) { - public CompanyByIdWithFalseConditions(int id) - { - Query.Where(x => x.Id == id, false) - .OrderBy(x => x.Id, false) - .ThenBy(x => x.Name) - .ThenByDescending(x => x.Name) - .OrderByDescending(x => x.Id, false) - .ThenBy(x => x.Name) - .ThenByDescending(x => x.Name) - .Include(x => x.Stores, false) - .ThenInclude(x => x.Products) - .Include(nameof(Store), false) - .Take(10, false) - .Skip(10, false) - .AsNoTracking(false) - .AsNoTrackingWithIdentityResolution(false) - .AsSplitQuery(false) - .IgnoreQueryFilters(false) - .Search(x => x.Name!, "asd", false) - .EnableCache(nameof(CompanyByIdWithFalseConditions), false, id); - } + Query.Where(x => x.Id == id, false) + .OrderBy(x => x.Id, false) + .ThenBy(x => x.Name) + .ThenByDescending(x => x.Name) + .OrderByDescending(x => x.Id, false) + .ThenBy(x => x.Name) + .ThenByDescending(x => x.Name) + .Include(x => x.Stores, false) + .ThenInclude(x => x.Products) + .Include(nameof(Store), false) + .Take(10, false) + .Skip(10, false) + .AsNoTracking(false) + .AsNoTrackingWithIdentityResolution(false) + .AsSplitQuery(false) + .IgnoreQueryFilters(false) + .Search(x => x.Name!, "asd", false) + .EnableCache(nameof(CompanyByIdWithFalseConditions), false, id); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdWithFalseConditionsForInnerChains.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdWithFalseConditionsForInnerChains.cs index 4d64b3ba..8b1d58eb 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdWithFalseConditionsForInnerChains.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdWithFalseConditionsForInnerChains.cs @@ -1,30 +1,27 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class CompanyByIdWithFalseConditionsForInnerChains : Specification, ISingleResultSpecification { - public class CompanyByIdWithFalseConditionsForInnerChains : Specification, ISingleResultSpecification + public CompanyByIdWithFalseConditionsForInnerChains(int id) { - public CompanyByIdWithFalseConditionsForInnerChains(int id) - { - Query.Where(x => x.Id == id, false) - .OrderBy(x => x.Id) - .ThenBy(x => x.Name, false) - .ThenByDescending(x => x.Name) - .OrderByDescending(x => x.Id) - .ThenByDescending(x => x.Name, false) - .ThenBy(x => x.Name) - .Include(x => x.Stores) - .ThenInclude(x => x.Products, false) - .ThenInclude(x => x.Store) - .Include(nameof(Store), false) - .Take(10, false) - .Skip(10, false) - .AsNoTracking(false) - .AsNoTrackingWithIdentityResolution(false) - .AsSplitQuery(false) - .IgnoreQueryFilters(false) - .Search(x => x.Name!, "asd", false) - .EnableCache(nameof(CompanyByIdWithFalseConditions), false, id); - } + Query.Where(x => x.Id == id, false) + .OrderBy(x => x.Id) + .ThenBy(x => x.Name, false) + .ThenByDescending(x => x.Name) + .OrderByDescending(x => x.Id) + .ThenByDescending(x => x.Name, false) + .ThenBy(x => x.Name) + .Include(x => x.Stores) + .ThenInclude(x => x.Products, false) + .ThenInclude(x => x.Store) + .Include(nameof(Store), false) + .Take(10, false) + .Skip(10, false) + .AsNoTracking(false) + .AsNoTrackingWithIdentityResolution(false) + .AsSplitQuery(false) + .IgnoreQueryFilters(false) + .Search(x => x.Name!, "asd", false) + .EnableCache(nameof(CompanyByIdWithFalseConditions), false, id); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdAndNameSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdAndNameSpec.cs index 959acd2c..f6b4b533 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdAndNameSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdAndNameSpec.cs @@ -1,13 +1,10 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoreByIdAndNameSpec : Specification { - public class StoreByIdAndNameSpec : Specification + public StoreByIdAndNameSpec(int id, string name) { - public StoreByIdAndNameSpec(int Id, string name) - { - Query.Where(x => x.Id == Id) - .Where(x => x.Name == name); - } + Query.Where(x => x.Id == id) + .Where(x => x.Name == name); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdIncludeAddressAndProductsSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdIncludeAddressAndProductsSpec.cs index 7534700f..c45ae556 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdIncludeAddressAndProductsSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdIncludeAddressAndProductsSpec.cs @@ -1,14 +1,11 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoreByIdIncludeAddressAndProductsSpec : Specification, ISingleResultSpecification { - public class StoreByIdIncludeAddressAndProductsSpec : Specification, ISingleResultSpecification + public StoreByIdIncludeAddressAndProductsSpec(int id) { - public StoreByIdIncludeAddressAndProductsSpec(int id) - { - Query.Where(x => x.Id == id); - Query.Include(x => x.Address); - Query.Include(x => x.Products); - } + Query.Where(x => x.Id == id); + Query.Include(x => x.Address); + Query.Include(x => x.Products); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdIncludeAddressSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdIncludeAddressSpec.cs index 37f50348..d8eecff1 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdIncludeAddressSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdIncludeAddressSpec.cs @@ -1,13 +1,10 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoreByIdIncludeAddressSpec : Specification, ISingleResultSpecification { - public class StoreByIdIncludeAddressSpec : Specification, ISingleResultSpecification + public StoreByIdIncludeAddressSpec(int id) { - public StoreByIdIncludeAddressSpec(int id) - { - Query.Where(x => x.Id == id) - .Include(x => x.Address); - } + Query.Where(x => x.Id == id) + .Include(x => x.Address); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdIncludeCompanyAndCountryAndStoresForCompanySpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdIncludeCompanyAndCountryAndStoresForCompanySpec.cs index 8c55bb14..2722eb83 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdIncludeCompanyAndCountryAndStoresForCompanySpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdIncludeCompanyAndCountryAndStoresForCompanySpec.cs @@ -1,14 +1,11 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoreByIdIncludeCompanyAndCountryAndStoresForCompanySpec : Specification, ISingleResultSpecification { - public class StoreByIdIncludeCompanyAndCountryAndStoresForCompanySpec : Specification, ISingleResultSpecification + public StoreByIdIncludeCompanyAndCountryAndStoresForCompanySpec(int id) { - public StoreByIdIncludeCompanyAndCountryAndStoresForCompanySpec(int id) - { - Query.Where(x => x.Id == id); - Query.Include(x => x.Company).ThenInclude(x => x!.Country); - Query.Include(x => x.Company).ThenInclude(x => x!.Stores).ThenInclude(x => x.Products); - } + Query.Where(x => x.Id == id); + Query.Include(x => x.Company).ThenInclude(x => x!.Country); + Query.Include(x => x.Company).ThenInclude(x => x!.Stores).ThenInclude(x => x.Products); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdIncludeProductsSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdIncludeProductsSpec.cs index a8bcb0b7..d366f739 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdIncludeProductsSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdIncludeProductsSpec.cs @@ -1,13 +1,10 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoreByIdIncludeProductsSpec : Specification, ISingleResultSpecification { - public class StoreByIdIncludeProductsSpec : Specification, ISingleResultSpecification + public StoreByIdIncludeProductsSpec(int id) { - public StoreByIdIncludeProductsSpec(int id) - { - Query.Where(x => x.Id == id) - .Include(x => x.Products); - } + Query.Where(x => x.Id == id) + .Include(x => x.Products); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdIncludeProductsUsingStringSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdIncludeProductsUsingStringSpec.cs index 97272316..9fd5c7b3 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdIncludeProductsUsingStringSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdIncludeProductsUsingStringSpec.cs @@ -1,13 +1,10 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoreByIdIncludeProductsUsingStringSpec : Specification, ISingleResultSpecification { - public class StoreByIdIncludeProductsUsingStringSpec : Specification, ISingleResultSpecification + public StoreByIdIncludeProductsUsingStringSpec(int id) { - public StoreByIdIncludeProductsUsingStringSpec(int id) - { - Query.Where(x => x.Id == id) - .Include(nameof(Store.Products)); - } + Query.Where(x => x.Id == id) + .Include(nameof(Store.Products)); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdSearchByNameAndCitySpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdSearchByNameAndCitySpec.cs index e5125d9e..8a71611e 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdSearchByNameAndCitySpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdSearchByNameAndCitySpec.cs @@ -1,14 +1,11 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoreByIdSearchByNameAndCitySpec : Specification { - public class StoreByIdSearchByNameAndCitySpec : Specification + public StoreByIdSearchByNameAndCitySpec(int id, string searchTerm) { - public StoreByIdSearchByNameAndCitySpec(int id, string searchTerm) - { - Query.Where(x => x.Id == id) - .Search(x => x.Name!, "%" + searchTerm + "%", 1) - .Search(x => x.City!, "%" + searchTerm + "%", 2); - } + Query.Where(x => x.Id == id) + .Search(x => x.Name!, "%" + searchTerm + "%", 1) + .Search(x => x.City!, "%" + searchTerm + "%", 2); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdSearchByNameOrCitySpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdSearchByNameOrCitySpec.cs index 626b6d4c..a7c7fc9c 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdSearchByNameOrCitySpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdSearchByNameOrCitySpec.cs @@ -1,14 +1,11 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoreByIdSearchByNameOrCitySpec : Specification { - public class StoreByIdSearchByNameOrCitySpec : Specification + public StoreByIdSearchByNameOrCitySpec(int id, string searchTerm) { - public StoreByIdSearchByNameOrCitySpec(int id, string searchTerm) - { - Query.Where(x => x.Id == id) - .Search(x => x.Name!, "%" + searchTerm + "%") - .Search(x => x.City!, "%" + searchTerm + "%"); - } + Query.Where(x => x.Id == id) + .Search(x => x.Name!, "%" + searchTerm + "%") + .Search(x => x.City!, "%" + searchTerm + "%"); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdSpec.cs index 275d92ec..d5e36842 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdSpec.cs @@ -1,12 +1,9 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoreByIdSpec : Specification { - public class StoreByIdSpec : Specification + public StoreByIdSpec(int id) { - public StoreByIdSpec(int Id) - { - Query.Where(x => x.Id == Id); - } + Query.Where(x => x.Id == id); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreDuplicateSkipSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreDuplicateSkipSpec.cs index 30269ad6..29cf9128 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreDuplicateSkipSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreDuplicateSkipSpec.cs @@ -1,13 +1,10 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoreDuplicateSkipSpec : Specification { - public class StoreDuplicateSkipSpec : Specification + public StoreDuplicateSkipSpec() { - public StoreDuplicateSkipSpec() - { - Query.Skip(1) - .Skip(2); - } + Query.Skip(1) + .Skip(2); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreDuplicateTakeSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreDuplicateTakeSpec.cs index 7c57fcab..f20d4082 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreDuplicateTakeSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreDuplicateTakeSpec.cs @@ -1,13 +1,10 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoreDuplicateTakeSpec : Specification { - public class StoreDuplicateTakeSpec : Specification + public StoreDuplicateTakeSpec() { - public StoreDuplicateTakeSpec() - { - Query.Take(1) - .Take(2); - } + Query.Take(1) + .Take(2); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreEmptySpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreEmptySpec.cs index 4d0bc45b..e43fe15f 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreEmptySpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreEmptySpec.cs @@ -1,12 +1,9 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoreEmptySpec : Specification { - public class StoreEmptySpec : Specification + public StoreEmptySpec() { - public StoreEmptySpec() - { - } } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreNamesEmptySpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreNamesEmptySpec.cs index 2593d0b9..2887bdcd 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreNamesEmptySpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreNamesEmptySpec.cs @@ -1,12 +1,9 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoreNamesEmptySpec : Specification { - public class StoreNamesEmptySpec : Specification + public StoreNamesEmptySpec() { - public StoreNamesEmptySpec() - { - } } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreNamesPaginatedSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreNamesPaginatedSpec.cs index f15756f4..340ba6bb 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreNamesPaginatedSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreNamesPaginatedSpec.cs @@ -1,16 +1,13 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoreNamesPaginatedSpec : Specification { - public class StoreNamesPaginatedSpec : Specification + public StoreNamesPaginatedSpec(int skip, int take) { - public StoreNamesPaginatedSpec(int skip, int take) - { - Query.OrderBy(x => x.Id) - .Skip(skip) - .Take(take); + Query.OrderBy(x => x.Id) + .Skip(skip) + .Take(take); - Query.Select(x => x.Name); - } + Query.Select(x => x.Name); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreNamesSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreNamesSpec.cs index 38a3ad4c..c4cc0cb4 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreNamesSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreNamesSpec.cs @@ -1,12 +1,9 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoreNamesSpec : Specification { - public class StoreNamesSpec : Specification + public StoreNamesSpec() { - public StoreNamesSpec() - { - Query.Select(x => x.Name); - } + Query.Select(x => x.Name); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreNamesWithPostProcessingActionSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreNamesWithPostProcessingActionSpec.cs index 44d85f05..a7295ef4 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreNamesWithPostProcessingActionSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreNamesWithPostProcessingActionSpec.cs @@ -1,13 +1,10 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoreNamesWithPostProcessingActionSpec : Specification { - public class StoreNamesWithPostProcessingActionSpec : Specification + public StoreNamesWithPostProcessingActionSpec() { - public StoreNamesWithPostProcessingActionSpec() - { - Query.Select(x => x.Name) - .PostProcessingAction(x => x); - } + Query.Select(x => x.Name) + .PostProcessingAction(x => x); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreProductNamesEmptySpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreProductNamesEmptySpec.cs index 56d82fa2..3312462c 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreProductNamesEmptySpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreProductNamesEmptySpec.cs @@ -1,12 +1,9 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoreProductNamesEmptySpec : Specification { - public class StoreProductNamesEmptySpec : Specification + public StoreProductNamesEmptySpec() { - public StoreProductNamesEmptySpec() - { - } } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreProductNamesSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreProductNamesSpec.cs index 401c35bd..2a45e21c 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreProductNamesSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreProductNamesSpec.cs @@ -1,13 +1,9 @@ -using System.Linq; -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoreProductNamesSpec : Specification { - public class StoreProductNamesSpec : Specification + public StoreProductNamesSpec() { - public StoreProductNamesSpec() - { - Query.SelectMany(s => s.Products.Select(p => p.Name)); - } + Query.SelectMany(s => s.Products.Select(p => p.Name)); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreSearchByNameAndCitySpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreSearchByNameAndCitySpec.cs index 3efccacc..0ac2e13f 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreSearchByNameAndCitySpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreSearchByNameAndCitySpec.cs @@ -1,13 +1,10 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoreSearchByNameAndCitySpec : Specification { - public class StoreSearchByNameAndCitySpec : Specification + public StoreSearchByNameAndCitySpec(string searchTerm) { - public StoreSearchByNameAndCitySpec(string searchTerm) - { - Query.Search(x => x.Name!, "%" + searchTerm + "%", 1) - .Search(x => x.City!, "%" + searchTerm + "%", 2); - } + Query.Search(x => x.Name!, "%" + searchTerm + "%", 1) + .Search(x => x.City!, "%" + searchTerm + "%", 2); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreSearchByNameOrCitySpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreSearchByNameOrCitySpec.cs index 643f0a1c..f442fcd7 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreSearchByNameOrCitySpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreSearchByNameOrCitySpec.cs @@ -1,13 +1,10 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoreSearchByNameOrCitySpec : Specification { - public class StoreSearchByNameOrCitySpec : Specification + public StoreSearchByNameOrCitySpec(string searchTerm) { - public StoreSearchByNameOrCitySpec(string searchTerm) - { - Query.Search(x => x.Name!, "%" + searchTerm + "%") - .Search(x => x.City!, "%" + searchTerm + "%"); - } + Query.Search(x => x.Name!, "%" + searchTerm + "%") + .Search(x => x.City!, "%" + searchTerm + "%"); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreSearchByNameSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreSearchByNameSpec.cs index 3cd31ca6..7f61ad28 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreSearchByNameSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreSearchByNameSpec.cs @@ -1,12 +1,9 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoreSearchByNameSpec : Specification { - public class StoreSearchByNameSpec : Specification + public StoreSearchByNameSpec(string searchTerm) { - public StoreSearchByNameSpec(string searchTerm) - { - Query.Search(x => x.Name!, "%" + searchTerm + "%"); - } + Query.Search(x => x.Name!, "%" + searchTerm + "%"); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreWithPostProcessingActionSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreWithPostProcessingActionSpec.cs index a8d93937..e9cdfdd2 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreWithPostProcessingActionSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreWithPostProcessingActionSpec.cs @@ -1,12 +1,9 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoreWithPostProcessingActionSpec : Specification { - public class StoreWithPostProcessingActionSpec : Specification + public StoreWithPostProcessingActionSpec() { - public StoreWithPostProcessingActionSpec() - { - Query.PostProcessingAction(x => x); - } + Query.PostProcessingAction(x => x); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByCompanyOrderedDescByNameSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByCompanyOrderedDescByNameSpec.cs index 1d805b02..50c2852f 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByCompanyOrderedDescByNameSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByCompanyOrderedDescByNameSpec.cs @@ -1,13 +1,10 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoresByCompanyOrderedDescByNameSpec : Specification { - public class StoresByCompanyOrderedDescByNameSpec : Specification + public StoresByCompanyOrderedDescByNameSpec(int companyId) { - public StoresByCompanyOrderedDescByNameSpec(int companyId) - { - Query.Where(x => x.CompanyId == companyId) - .OrderByDescending(x => x.Name); - } + Query.Where(x => x.CompanyId == companyId) + .OrderByDescending(x => x.Name); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByCompanyOrderedDescByNameThenByDescIdSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByCompanyOrderedDescByNameThenByDescIdSpec.cs index 5e7e2581..1caef272 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByCompanyOrderedDescByNameThenByDescIdSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByCompanyOrderedDescByNameThenByDescIdSpec.cs @@ -1,14 +1,11 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoresByCompanyOrderedDescByNameThenByDescIdSpec : Specification { - public class StoresByCompanyOrderedDescByNameThenByDescIdSpec : Specification + public StoresByCompanyOrderedDescByNameThenByDescIdSpec(int companyId) { - public StoresByCompanyOrderedDescByNameThenByDescIdSpec(int companyId) - { - Query.Where(x => x.CompanyId == companyId) - .OrderByDescending(x => x.Name) - .ThenByDescending(x => x.Id); - } + Query.Where(x => x.CompanyId == companyId) + .OrderByDescending(x => x.Name) + .ThenByDescending(x => x.Id); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByCompanyOrderedDescByNameThenByIdSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByCompanyOrderedDescByNameThenByIdSpec.cs index fbf6f944..c14fcbcc 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByCompanyOrderedDescByNameThenByIdSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByCompanyOrderedDescByNameThenByIdSpec.cs @@ -1,14 +1,11 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoresByCompanyOrderedDescByNameThenByIdSpec : Specification { - public class StoresByCompanyOrderedDescByNameThenByIdSpec : Specification + public StoresByCompanyOrderedDescByNameThenByIdSpec(int companyId) { - public StoresByCompanyOrderedDescByNameThenByIdSpec(int companyId) - { - Query.Where(x => x.CompanyId == companyId) - .OrderByDescending(x => x.Name) - .ThenBy(x => x.Id); - } + Query.Where(x => x.CompanyId == companyId) + .OrderByDescending(x => x.Name) + .ThenBy(x => x.Id); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByCompanyPaginatedOrderedDescByNameSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByCompanyPaginatedOrderedDescByNameSpec.cs index 21e171ba..12dc0ecb 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByCompanyPaginatedOrderedDescByNameSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByCompanyPaginatedOrderedDescByNameSpec.cs @@ -1,19 +1,12 @@ -using System; -using System.Collections.Generic; -using System.Text; -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; - -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoresByCompanyPaginatedOrderedDescByNameSpec : Specification { - public class StoresByCompanyPaginatedOrderedDescByNameSpec : Specification + public StoresByCompanyPaginatedOrderedDescByNameSpec(int companyId, int skip, int take) { - public StoresByCompanyPaginatedOrderedDescByNameSpec(int companyId, int skip, int take) - { - Query.Where(x => x.CompanyId == companyId) - .Skip(skip) - .Take(take) - .OrderByDescending(x => x.Name); - } + Query.Where(x => x.CompanyId == companyId) + .Skip(skip) + .Take(take) + .OrderByDescending(x => x.Name); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByCompanyPaginatedSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByCompanyPaginatedSpec.cs index a7520152..b4f77ada 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByCompanyPaginatedSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByCompanyPaginatedSpec.cs @@ -1,15 +1,12 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoresByCompanyPaginatedSpec : Specification { - public class StoresByCompanyPaginatedSpec : Specification + public StoresByCompanyPaginatedSpec(int companyId, int skip, int take) { - public StoresByCompanyPaginatedSpec(int companyId, int skip, int take) - { - Query.Where(x => x.CompanyId == companyId) - .OrderBy(x => x.CompanyId) - .Skip(skip) - .Take(take); - } + Query.Where(x => x.CompanyId == companyId) + .OrderBy(x => x.CompanyId) + .Skip(skip) + .Take(take); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByIdListSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByIdListSpec.cs index 7e389f9b..1ee40d44 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByIdListSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByIdListSpec.cs @@ -1,15 +1,12 @@ using System; using System.Collections.Generic; -using System.Linq; -using Ardalis.Specification.UnitTests.Fixture.Entities; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +namespace Ardalis.Specification.UnitTests.Fixture.Specs; + +public class StoresByIdListSpec : Specification { - public class StoresByIdListSpec : Specification + public StoresByIdListSpec(IEnumerable ids) { - public StoresByIdListSpec(IEnumerable Ids) - { - Query.Where(x => Ids.Contains(x.Id)); - } + Query.Where(x => ids.Contains(x.Id)); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresOrderedDescendingByNameSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresOrderedDescendingByNameSpec.cs index cbd3632e..0f754495 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresOrderedDescendingByNameSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresOrderedDescendingByNameSpec.cs @@ -1,12 +1,9 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoresOrderedDescendingByNameSpec : Specification { - public class StoresOrderedDescendingByNameSpec : Specification + public StoresOrderedDescendingByNameSpec() { - public StoresOrderedDescendingByNameSpec() - { - Query.OrderByDescending(x => x.Name); - } + Query.OrderByDescending(x => x.Name); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresOrderedSpecByName.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresOrderedSpecByName.cs index de1d9dcb..d45f7665 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresOrderedSpecByName.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresOrderedSpecByName.cs @@ -1,12 +1,9 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoresOrderedSpecByName : Specification { - public class StoresOrderedSpecByName : Specification + public StoresOrderedSpecByName() { - public StoresOrderedSpecByName() - { - Query.OrderBy(x => x.Name); - } + Query.OrderBy(x => x.Name); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresOrderedTwoChainsSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresOrderedTwoChainsSpec.cs index 1de74c49..4aa1fd9f 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresOrderedTwoChainsSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresOrderedTwoChainsSpec.cs @@ -1,13 +1,10 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoresOrderedTwoChainsSpec : Specification { - public class StoresOrderedTwoChainsSpec : Specification + public StoresOrderedTwoChainsSpec() { - public StoresOrderedTwoChainsSpec() - { - Query.OrderBy(x => x.Name) - .OrderBy(x => x.Id); - } + Query.OrderBy(x => x.Name) + .OrderBy(x => x.Id); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresPaginatedSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresPaginatedSpec.cs index 62fb5834..21b7db63 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresPaginatedSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresPaginatedSpec.cs @@ -1,14 +1,11 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoresPaginatedSpec : Specification { - public class StoresPaginatedSpec : Specification + public StoresPaginatedSpec(int skip, int take) { - public StoresPaginatedSpec(int skip, int take) - { - Query.OrderBy(s => s.Id) - .Skip(skip) - .Take(take); - } + Query.OrderBy(s => s.Id) + .Skip(skip) + .Take(take); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/CompanyIncludeFilteredStoresSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/CompanyIncludeFilteredStoresSpec.cs index 4a1c614a..43ae00c6 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/CompanyIncludeFilteredStoresSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/CompanyIncludeFilteredStoresSpec.cs @@ -1,17 +1,10 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class CompanyIncludeFilteredStoresSpec : Specification { - public class CompanyIncludeFilteredStoresSpec : Specification + public CompanyIncludeFilteredStoresSpec(int id) { - public CompanyIncludeFilteredStoresSpec(int id) - { - Query.Where(x => x.Id == id) - .Include(x => x.Stores.Where(s => s.Id == 1)); - } + Query.Where(x => x.Id == id) + .Include(x => x.Stores.Where(s => s.Id == 1)); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeAddressAndProductsSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeAddressAndProductsSpec.cs index eeb278b5..9352d180 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeAddressAndProductsSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeAddressAndProductsSpec.cs @@ -1,16 +1,10 @@ -using System; -using System.Collections.Generic; -using System.Text; -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoreIncludeAddressAndProductsSpec : Specification { - public class StoreIncludeAddressAndProductsSpec : Specification + public StoreIncludeAddressAndProductsSpec() { - public StoreIncludeAddressAndProductsSpec() - { - Query.Include(x => x.Products) - .Include(x => x!.Address); - } + Query.Include(x => x.Products) + .Include(x => x!.Address); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeAddressSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeAddressSpec.cs index 7190c595..9c37e1fb 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeAddressSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeAddressSpec.cs @@ -1,15 +1,9 @@ -using System; -using System.Collections.Generic; -using System.Text; -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoreIncludeAddressSpec : Specification { - public class StoreIncludeAddressSpec : Specification + public StoreIncludeAddressSpec() { - public StoreIncludeAddressSpec() - { - Query.Include(x => x.Address); - } + Query.Include(x => x.Address); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeCompanyCountryDotSeparatedSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeCompanyCountryDotSeparatedSpec.cs index a38ac825..91ff257a 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeCompanyCountryDotSeparatedSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeCompanyCountryDotSeparatedSpec.cs @@ -1,15 +1,9 @@ -using System; -using System.Collections.Generic; -using System.Text; -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoreIncludeCompanyCountryDotSeparatedSpec : Specification { - public class StoreIncludeCompanyCountryDotSeparatedSpec : Specification + public StoreIncludeCompanyCountryDotSeparatedSpec() { - public StoreIncludeCompanyCountryDotSeparatedSpec() - { - Query.Include(x => x.Company!.Country); - } + Query.Include(x => x.Company!.Country); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeCompanyThenCountryAsStringSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeCompanyThenCountryAsStringSpec.cs index 1d06bb3c..4d76c1a3 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeCompanyThenCountryAsStringSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeCompanyThenCountryAsStringSpec.cs @@ -1,15 +1,9 @@ -using System; -using System.Collections.Generic; -using System.Text; -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoreIncludeCompanyThenCountryAsStringSpec : Specification { - public class StoreIncludeCompanyThenCountryAsStringSpec : Specification + public StoreIncludeCompanyThenCountryAsStringSpec() { - public StoreIncludeCompanyThenCountryAsStringSpec() - { - Query.Include($"{nameof(Company)}.{nameof(Company.Country)}"); - } + Query.Include($"{nameof(Company)}.{nameof(Company.Country)}"); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeCompanyThenCountrySpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeCompanyThenCountrySpec.cs index efbadcf0..7f8f0c11 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeCompanyThenCountrySpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeCompanyThenCountrySpec.cs @@ -1,16 +1,10 @@ -using System; -using System.Collections.Generic; -using System.Text; -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoreIncludeCompanyThenCountrySpec : Specification { - public class StoreIncludeCompanyThenCountrySpec : Specification + public StoreIncludeCompanyThenCountrySpec() { - public StoreIncludeCompanyThenCountrySpec() - { - Query.Include(x => x.Company) - .ThenInclude(x => x!.Country); - } + Query.Include(x => x.Company) + .ThenInclude(x => x!.Country); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeCompanyThenNameSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeCompanyThenNameSpec.cs index a41f8979..20348593 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeCompanyThenNameSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeCompanyThenNameSpec.cs @@ -1,16 +1,10 @@ -using System; -using System.Collections.Generic; -using System.Text; -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoreIncludeCompanyThenNameSpec : Specification { - public class StoreIncludeCompanyThenNameSpec : Specification + public StoreIncludeCompanyThenNameSpec() { - public StoreIncludeCompanyThenNameSpec() - { - Query.Include(x => x.Company) - .ThenInclude(x => x!.Name); - } + Query.Include(x => x.Company) + .ThenInclude(x => x!.Name); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeCompanyThenStoresSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeCompanyThenStoresSpec.cs index c23482a6..1413021b 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeCompanyThenStoresSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeCompanyThenStoresSpec.cs @@ -1,14 +1,11 @@ -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoreIncludeCompanyThenStoresSpec : Specification { - public class StoreIncludeCompanyThenStoresSpec : Specification + public StoreIncludeCompanyThenStoresSpec() { - public StoreIncludeCompanyThenStoresSpec() - { - Query.Include(x => x.Company) - .ThenInclude(x => x!.Stores) - .ThenInclude(x => x.Products); - } + Query.Include(x => x.Company) + .ThenInclude(x => x!.Stores) + .ThenInclude(x => x.Products); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeMethodOfNavigationSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeMethodOfNavigationSpec.cs index fe8f7af6..e4b1bba6 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeMethodOfNavigationSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeMethodOfNavigationSpec.cs @@ -1,15 +1,9 @@ -using System; -using System.Collections.Generic; -using System.Text; -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoreIncludeMethodOfNavigationSpec : Specification { - public class StoreIncludeMethodOfNavigationSpec : Specification + public StoreIncludeMethodOfNavigationSpec() { - public StoreIncludeMethodOfNavigationSpec() - { - Query.Include(x => x.Address!.GetSomethingFromAddress()); - } + Query.Include(x => x.Address!.GetSomethingFromAddress()); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeMethodSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeMethodSpec.cs index 5b7599de..f9cce94a 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeMethodSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeMethodSpec.cs @@ -1,15 +1,9 @@ -using System; -using System.Collections.Generic; -using System.Text; -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoreIncludeMethodSpec : Specification { - public class StoreIncludeMethodSpec : Specification + public StoreIncludeMethodSpec() { - public StoreIncludeMethodSpec() - { - Query.Include(x => x.GetSomethingFromStore()); - } + Query.Include(x => Store.GetSomethingFromStore()); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeNameSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeNameSpec.cs index 9ace7e9e..d52f326d 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeNameSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeNameSpec.cs @@ -1,15 +1,9 @@ -using System; -using System.Collections.Generic; -using System.Text; -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoreIncludeNameSpec : Specification { - public class StoreIncludeNameSpec : Specification + public StoreIncludeNameSpec() { - public StoreIncludeNameSpec() - { - Query.Include(x => x.Name); - } + Query.Include(x => x.Name); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeProductsSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeProductsSpec.cs index 44a235bd..3fd09d25 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeProductsSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeProductsSpec.cs @@ -1,15 +1,9 @@ -using System; -using System.Collections.Generic; -using System.Text; -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoreIncludeProductsSpec : Specification { - public class StoreIncludeProductsSpec : Specification + public StoreIncludeProductsSpec() { - public StoreIncludeProductsSpec() - { - Query.Include(x => x.Products); - } + Query.Include(x => x.Products); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreWithFaultyIncludeSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreWithFaultyIncludeSpec.cs index 35dabccd..1bd37bf3 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreWithFaultyIncludeSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreWithFaultyIncludeSpec.cs @@ -1,15 +1,9 @@ -using System; -using System.Collections.Generic; -using System.Text; -using Ardalis.Specification.UnitTests.Fixture.Entities; +namespace Ardalis.Specification.UnitTests.Fixture.Specs; -namespace Ardalis.Specification.UnitTests.Fixture.Specs +public class StoreWithFaultyIncludeSpec : Specification { - public class StoreWithFaultyIncludeSpec : Specification + public StoreWithFaultyIncludeSpec() { - public StoreWithFaultyIncludeSpec() - { - Query.Include(x => x.Id == 1 && x.Name == "Something"); - } + Query.Include(x => x.Id == 1 && x.Name == "Something"); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/GlobalUsings.cs b/Specification/tests/Ardalis.Specification.UnitTests/GlobalUsings.cs new file mode 100644 index 00000000..9553d65e --- /dev/null +++ b/Specification/tests/Ardalis.Specification.UnitTests/GlobalUsings.cs @@ -0,0 +1,5 @@ +global using Ardalis.Specification.UnitTests.Fixture.Entities; +global using Ardalis.Specification.UnitTests.Fixture.Specs; +global using FluentAssertions; +global using System.Linq; +global using Xunit; diff --git a/Specification/tests/Ardalis.Specification.UnitTests/IncludeExpressionInfoTests.cs b/Specification/tests/Ardalis.Specification.UnitTests/IncludeExpressionInfoTests.cs index b4e930ab..184145a3 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/IncludeExpressionInfoTests.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/IncludeExpressionInfoTests.cs @@ -1,54 +1,50 @@ using System; using System.Linq.Expressions; -using Ardalis.Specification.UnitTests.Fixture.Entities; -using FluentAssertions; -using Xunit; -namespace Ardalis.Specification.UnitTests +namespace Ardalis.Specification.UnitTests; + +public class IncludeExpressionInfoTests { - public class IncludeExpressionInfoTests + private readonly Expression> _expr; + + public IncludeExpressionInfoTests() + { + _expr = x => x.Country!; + } + + [Fact] + public void ThrowsArgumentNullException_GivenNullForLambdaExpression() + { + Action sutAction = () => new IncludeExpressionInfo(null!, typeof(Company), typeof(Country)); + + sutAction.Should() + .Throw(); + } + + [Fact] + public void ThrowsArgumentNullException_GivenNullForEntityType() { - private readonly Expression> expr; - - public IncludeExpressionInfoTests() - { - expr = x => x.Country!; - } - - [Fact] - public void ThrowsArgumentNullException_GivenNullForLambdaExpression() - { - Action sutAction = () => new IncludeExpressionInfo(null!, typeof(Company), typeof(Country)); - - sutAction.Should() - .Throw(); - } - - [Fact] - public void ThrowsArgumentNullException_GivenNullForEntityType() - { - Action sutAction = () => new IncludeExpressionInfo(expr, null!, typeof(Country)); - - sutAction.Should() - .Throw(); - } - - [Fact] - public void ThrowsArgumentNullException_GivenNullForPropertyType() - { - Action sutAction = () => new IncludeExpressionInfo(expr, typeof(Company), null!); - - sutAction.Should() - .Throw(); - } - - [Fact] - public void ThrowsArgumentNullException_GivenNullForPreviousPropertyType() - { - Action sutAction = () => new IncludeExpressionInfo(expr, typeof(Company), typeof(Country), null!); - - sutAction.Should() - .Throw(); - } + Action sutAction = () => new IncludeExpressionInfo(_expr, null!, typeof(Country)); + + sutAction.Should() + .Throw(); + } + + [Fact] + public void ThrowsArgumentNullException_GivenNullForPropertyType() + { + Action sutAction = () => new IncludeExpressionInfo(_expr, typeof(Company), null!); + + sutAction.Should() + .Throw(); + } + + [Fact] + public void ThrowsArgumentNullException_GivenNullForPreviousPropertyType() + { + Action sutAction = () => new IncludeExpressionInfo(_expr, typeof(Company), typeof(Country), null!); + + sutAction.Should() + .Throw(); } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/ValidatorTests/SpecificationValidator_Tests.cs b/Specification/tests/Ardalis.Specification.UnitTests/ValidatorTests/SpecificationValidator_Tests.cs index e9d4b309..cfe92db1 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/ValidatorTests/SpecificationValidator_Tests.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/ValidatorTests/SpecificationValidator_Tests.cs @@ -1,98 +1,89 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Ardalis.Specification.UnitTests.Fixture.Entities; -using Ardalis.Specification.UnitTests.Fixture.Entities.Seeds; -using Ardalis.Specification.UnitTests.Fixture.Specs; -using FluentAssertions; - -namespace Ardalis.Specification.UnitTests.ValidatorTests +using Ardalis.Specification.UnitTests.Fixture.Entities.Seeds; + +namespace Ardalis.Specification.UnitTests.ValidatorTests; + +public class SpecificationValidator_Tests { - public class SpecificationValidator_Tests - { - Store store = StoreSeed.Get().Single(x => x.Id == StoreSeed.VALID_Search_ID); + private readonly Store _store = StoreSeed.Get().Single(x => x.Id == StoreSeed.VALID_Search_ID); - public void ReturnsTrue_GivenStoreByIdSearchByNameAndCitySpec_WithValidValues() - { - var spec = new StoreByIdSearchByNameAndCitySpec(StoreSeed.VALID_Search_ID, StoreSeed.VALID_Search_City_Name_Key); + public void ReturnsTrue_GivenStoreByIdSearchByNameAndCitySpec_WithValidValues() + { + var spec = new StoreByIdSearchByNameAndCitySpec(StoreSeed.VALID_Search_ID, StoreSeed.VALID_Search_City_Name_Key); - var result = spec.IsSatisfiedBy(store); + var result = spec.IsSatisfiedBy(_store); - result.Should().BeTrue(); - } + result.Should().BeTrue(); + } - public void ReturnsFalse_GivenStoreByIdSearchByNameAndCitySpec_WithInvalidId() - { - var spec = new StoreByIdSearchByNameAndCitySpec(1, StoreSeed.VALID_Search_City_Name_Key); + public void ReturnsFalse_GivenStoreByIdSearchByNameAndCitySpec_WithInvalidId() + { + var spec = new StoreByIdSearchByNameAndCitySpec(1, StoreSeed.VALID_Search_City_Name_Key); - var result = spec.IsSatisfiedBy(store); + var result = spec.IsSatisfiedBy(_store); - result.Should().BeFalse(); - } + result.Should().BeFalse(); + } - public void ReturnsFalse_GivenStoreByIdSearchByNameAndCitySpec_WithInvalidNameSearchString() - { - var spec = new StoreByIdSearchByNameAndCitySpec(StoreSeed.VALID_Search_ID, StoreSeed.VALID_Search_City_Key); + public void ReturnsFalse_GivenStoreByIdSearchByNameAndCitySpec_WithInvalidNameSearchString() + { + var spec = new StoreByIdSearchByNameAndCitySpec(StoreSeed.VALID_Search_ID, StoreSeed.VALID_Search_City_Key); - var result = spec.IsSatisfiedBy(store); + var result = spec.IsSatisfiedBy(_store); - result.Should().BeFalse(); - } + result.Should().BeFalse(); + } - public void ReturnsFalse_GivenStoreByIdSearchByNameAndCitySpec_WithInvalidCitySearchString() - { - var spec = new StoreByIdSearchByNameAndCitySpec(StoreSeed.VALID_Search_ID, StoreSeed.VALID_Search_Name_Key); + public void ReturnsFalse_GivenStoreByIdSearchByNameAndCitySpec_WithInvalidCitySearchString() + { + var spec = new StoreByIdSearchByNameAndCitySpec(StoreSeed.VALID_Search_ID, StoreSeed.VALID_Search_Name_Key); - var result = spec.IsSatisfiedBy(store); + var result = spec.IsSatisfiedBy(_store); - result.Should().BeFalse(); - } + result.Should().BeFalse(); + } - public void ReturnsFalse_StoreByIdSearchByNameAndCitySpecSpec_WithInvalidCityAndNameSearchString() - { - var spec = new StoreByIdSearchByNameAndCitySpec(StoreSeed.VALID_Search_ID, "random"); + public void ReturnsFalse_StoreByIdSearchByNameAndCitySpecSpec_WithInvalidCityAndNameSearchString() + { + var spec = new StoreByIdSearchByNameAndCitySpec(StoreSeed.VALID_Search_ID, "random"); - var result = spec.IsSatisfiedBy(store); + var result = spec.IsSatisfiedBy(_store); - result.Should().BeFalse(); - } + result.Should().BeFalse(); + } - public void ReturnsTrue_StoreByIdSearchByNameOrCitySpecSpec_WithValidValues() - { - var spec = new StoreByIdSearchByNameOrCitySpec(StoreSeed.VALID_Search_ID, StoreSeed.VALID_Search_City_Name_Key); + public void ReturnsTrue_StoreByIdSearchByNameOrCitySpecSpec_WithValidValues() + { + var spec = new StoreByIdSearchByNameOrCitySpec(StoreSeed.VALID_Search_ID, StoreSeed.VALID_Search_City_Name_Key); - var result = spec.IsSatisfiedBy(store); + var result = spec.IsSatisfiedBy(_store); - result.Should().BeTrue(); - } + result.Should().BeTrue(); + } - public void ReturnsTrue_StoreByIdSearchByNameOrCitySpecSpec_WithInvalidNameSearchString() - { - var spec = new StoreByIdSearchByNameOrCitySpec(StoreSeed.VALID_Search_ID, StoreSeed.VALID_Search_City_Key); + public void ReturnsTrue_StoreByIdSearchByNameOrCitySpecSpec_WithInvalidNameSearchString() + { + var spec = new StoreByIdSearchByNameOrCitySpec(StoreSeed.VALID_Search_ID, StoreSeed.VALID_Search_City_Key); - var result = spec.IsSatisfiedBy(store); + var result = spec.IsSatisfiedBy(_store); - result.Should().BeTrue(); - } + result.Should().BeTrue(); + } - public void ReturnsTrue_StoreByIdSearchByNameOrCitySpecSpec_WithInvalidCitySearchString() - { - var spec = new StoreByIdSearchByNameOrCitySpec(StoreSeed.VALID_Search_ID, StoreSeed.VALID_Search_Name_Key); + public void ReturnsTrue_StoreByIdSearchByNameOrCitySpecSpec_WithInvalidCitySearchString() + { + var spec = new StoreByIdSearchByNameOrCitySpec(StoreSeed.VALID_Search_ID, StoreSeed.VALID_Search_Name_Key); - var result = spec.IsSatisfiedBy(store); + var result = spec.IsSatisfiedBy(_store); - result.Should().BeTrue(); - } + result.Should().BeTrue(); + } - public void ReturnsFalse_StoreByIdSearchByNameOrCitySpecSpec_WithInvalidCityAndNameSearchString() - { - var spec = new StoreByIdSearchByNameOrCitySpec(StoreSeed.VALID_Search_ID, "random"); + public void ReturnsFalse_StoreByIdSearchByNameOrCitySpecSpec_WithInvalidCityAndNameSearchString() + { + var spec = new StoreByIdSearchByNameOrCitySpec(StoreSeed.VALID_Search_ID, "random"); - var result = spec.IsSatisfiedBy(store); + var result = spec.IsSatisfiedBy(_store); - result.Should().BeFalse(); - } + result.Should().BeFalse(); } } diff --git a/docker-compose.yml b/docker-compose.yml index e8d222de..90f2e300 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,7 +13,7 @@ services: - databaseEFCore databaseEFCore: - image: mcr.microsoft.com/mssql/server:2019-CU3-ubuntu-18.04 + image: mcr.microsoft.com/mssql/server:2022-latest environment: SA_PASSWORD: "P@ssW0rd!" ACCEPT_EULA: "Y" diff --git a/sample/Ardalis.SampleApp.Core/Ardalis.SampleApp.Core.csproj b/sample/Ardalis.SampleApp.Core/Ardalis.SampleApp.Core.csproj index 9edec766..ca9121ea 100644 --- a/sample/Ardalis.SampleApp.Core/Ardalis.SampleApp.Core.csproj +++ b/sample/Ardalis.SampleApp.Core/Ardalis.SampleApp.Core.csproj @@ -2,6 +2,7 @@ net6.0 + 11.0 diff --git a/sample/Ardalis.SampleApp.Core/Entities/CustomerAggregate/Customer.cs b/sample/Ardalis.SampleApp.Core/Entities/CustomerAggregate/Customer.cs index 0607c5a3..a9ed1faf 100644 --- a/sample/Ardalis.SampleApp.Core/Entities/CustomerAggregate/Customer.cs +++ b/sample/Ardalis.SampleApp.Core/Entities/CustomerAggregate/Customer.cs @@ -1,55 +1,54 @@ -using System.Collections.Generic; -using System.Linq; -using Ardalis.GuardClauses; +using Ardalis.GuardClauses; using Ardalis.SampleApp.Core.Interfaces; +using System.Collections.Generic; +using System.Linq; + +namespace Ardalis.SampleApp.Core.Entities.CustomerAggregate; -namespace Ardalis.SampleApp.Core.Entities.CustomerAggregate +public class Customer : IAggregateRoot { - public class Customer : IAggregateRoot - { - public int Id { get; private set; } - public string Name { get; private set; } - public string Email { get; private set; } - public string Address { get; private set; } + public int Id { get; private set; } + public string Name { get; private set; } + public string Email { get; private set; } + public string Address { get; private set; } - public IEnumerable Stores => _stores.AsEnumerable(); - private readonly List _stores = new List(); + public IEnumerable Stores => _stores.AsEnumerable(); + private readonly List _stores = new(); - public Customer(string name, string email, string address) - { - Guard.Against.NullOrEmpty(name, nameof(name)); - Guard.Against.NullOrEmpty(email, nameof(email)); + public Customer(string name, string email, string address) + { + Guard.Against.NullOrEmpty(name, nameof(name)); + Guard.Against.NullOrEmpty(email, nameof(email)); - this.Name = name; - this.Email = email; - this.Address = address; - } + Name = name; + Email = email; + Address = address; + } - public Store GetStore(int storeId) - { - var store = Stores.FirstOrDefault(x => x.Id == storeId); + public Store GetStore(int storeId) + { + var store = Stores.FirstOrDefault(x => x.Id == storeId); - Guard.Against.Null(store, nameof(store)); + Guard.Against.Null(store, nameof(store)); - return store; - } + return store; + } - public Store AddStore(Store store) - { - Guard.Against.Null(store, nameof(store)); + public Store AddStore(Store store) + { + Guard.Against.Null(store, nameof(store)); - // Do some other operation while adding it. + // Do some other operation while adding it. - _stores.Add(store); + _stores.Add(store); - return store; - } + return store; + } - public void DeleteStore(int storeID) - { - var store = GetStore(storeID); + public void DeleteStore(int storeID) + { + var store = GetStore(storeID); - _stores.Remove(store); - } + _stores.Remove(store); } } diff --git a/sample/Ardalis.SampleApp.Core/Entities/CustomerAggregate/Store.cs b/sample/Ardalis.SampleApp.Core/Entities/CustomerAggregate/Store.cs index 7c2a7ee2..ccbd4301 100644 --- a/sample/Ardalis.SampleApp.Core/Entities/CustomerAggregate/Store.cs +++ b/sample/Ardalis.SampleApp.Core/Entities/CustomerAggregate/Store.cs @@ -1,21 +1,20 @@ using Ardalis.GuardClauses; -namespace Ardalis.SampleApp.Core.Entities.CustomerAggregate +namespace Ardalis.SampleApp.Core.Entities.CustomerAggregate; + +public class Store { - public class Store - { - public int Id { get; private set; } - public string Name { get; private set; } - public string Address { get; private set; } + public int Id { get; private set; } + public string Name { get; private set; } + public string Address { get; private set; } - public int CustomerId { get; private set; } + public int CustomerId { get; private set; } - public Store(string name, string address) - { - Guard.Against.NullOrEmpty(name, nameof(name)); + public Store(string name, string address) + { + Guard.Against.NullOrEmpty(name, nameof(name)); - this.Name = name; - this.Address = address; - } + this.Name = name; + this.Address = address; } } diff --git a/sample/Ardalis.SampleApp.Core/Entities/Seeds/CustomerSeed.cs b/sample/Ardalis.SampleApp.Core/Entities/Seeds/CustomerSeed.cs index 6370e33a..543ff001 100644 --- a/sample/Ardalis.SampleApp.Core/Entities/Seeds/CustomerSeed.cs +++ b/sample/Ardalis.SampleApp.Core/Entities/Seeds/CustomerSeed.cs @@ -1,24 +1,23 @@ -using System.Collections.Generic; -using Ardalis.SampleApp.Core.Entities.CustomerAggregate; +using Ardalis.SampleApp.Core.Entities.CustomerAggregate; +using System.Collections.Generic; -namespace Ardalis.SampleApp.Core.Entities.Seeds +namespace Ardalis.SampleApp.Core.Entities.Seeds; + +public static class CustomerSeed { - public static class CustomerSeed + public static List Seed() { - public static List Seed() - { - List output = new List(); - - for (int i = 1; i <= 100000; i++) - { - var customer = new Customer($"Customer{i}", $"Email{i}@local", $"Customer{i} address"); - customer.AddStore(new Store($"Store{i}-1", $"Store{i}-1 address")); - customer.AddStore(new Store($"Store{i}-2", $"Store{i}-2 address")); + List output = new List(); - output.Add(customer); - } + for (int i = 1; i <= 100000; i++) + { + var customer = new Customer($"Customer{i}", $"Email{i}@local", $"Customer{i} address"); + customer.AddStore(new Store($"Store{i}-1", $"Store{i}-1 address")); + customer.AddStore(new Store($"Store{i}-2", $"Store{i}-2 address")); - return output; + output.Add(customer); } + + return output; } } diff --git a/sample/Ardalis.SampleApp.Core/Interfaces/IAggregateRoot.cs b/sample/Ardalis.SampleApp.Core/Interfaces/IAggregateRoot.cs index 0b98eb7b..13cf2d12 100644 --- a/sample/Ardalis.SampleApp.Core/Interfaces/IAggregateRoot.cs +++ b/sample/Ardalis.SampleApp.Core/Interfaces/IAggregateRoot.cs @@ -1,6 +1,5 @@ -namespace Ardalis.SampleApp.Core.Interfaces +namespace Ardalis.SampleApp.Core.Interfaces; + +public interface IAggregateRoot { - public interface IAggregateRoot - { - } } diff --git a/sample/Ardalis.SampleApp.Core/Interfaces/ICustomerRepository.cs b/sample/Ardalis.SampleApp.Core/Interfaces/ICustomerRepository.cs index fb77ec20..b2c947a9 100644 --- a/sample/Ardalis.SampleApp.Core/Interfaces/ICustomerRepository.cs +++ b/sample/Ardalis.SampleApp.Core/Interfaces/ICustomerRepository.cs @@ -1,12 +1,11 @@ -using System.Collections.Generic; +using Ardalis.SampleApp.Core.Entities.CustomerAggregate; +using System.Collections.Generic; using System.Threading.Tasks; -using Ardalis.SampleApp.Core.Entities.CustomerAggregate; -namespace Ardalis.SampleApp.Core.Interfaces +namespace Ardalis.SampleApp.Core.Interfaces; + +public interface ICustomerRepository { - public interface ICustomerRepository - { - // This is just to demonstrate that at anytime you can create custom repositories, and use to create some complex queries working directly with EF or your ORM. - Task> GetCustomers(string addressSearchTerm); - } + // This is just to demonstrate that at anytime you can create custom repositories, and use to create some complex queries working directly with EF or your ORM. + Task> GetCustomers(string addressSearchTerm); } diff --git a/sample/Ardalis.SampleApp.Core/Interfaces/IRepository.cs b/sample/Ardalis.SampleApp.Core/Interfaces/IRepository.cs index 27b1013d..1e6aa7ba 100644 --- a/sample/Ardalis.SampleApp.Core/Interfaces/IRepository.cs +++ b/sample/Ardalis.SampleApp.Core/Interfaces/IRepository.cs @@ -1,14 +1,13 @@ using Ardalis.Specification; -namespace Ardalis.SampleApp.Core.Interfaces +namespace Ardalis.SampleApp.Core.Interfaces; + +/// +public interface IRepository : IRepositoryBase where T : class, IAggregateRoot { - /// - public interface IRepository : IRepositoryBase where T : class, IAggregateRoot - { - } +} - /// - public interface IReadRepository : IReadRepositoryBase where T : class, IAggregateRoot - { - } +/// +public interface IReadRepository : IReadRepositoryBase where T : class, IAggregateRoot +{ } diff --git a/sample/Ardalis.SampleApp.Core/Specifications/CustomerByNameSpec.cs b/sample/Ardalis.SampleApp.Core/Specifications/CustomerByNameSpec.cs index 5f255d0f..a03b5a57 100644 --- a/sample/Ardalis.SampleApp.Core/Specifications/CustomerByNameSpec.cs +++ b/sample/Ardalis.SampleApp.Core/Specifications/CustomerByNameSpec.cs @@ -1,18 +1,17 @@ using Ardalis.SampleApp.Core.Entities.CustomerAggregate; using Ardalis.Specification; -namespace Ardalis.SampleApp.Core.Specifications +namespace Ardalis.SampleApp.Core.Specifications; + +/// +/// This specification expects customer names to be unique - change the base type if you want to support multiple results +/// +public class CustomerByNameSpec : SingleResultSpecification { - /// - /// This specification expects customer names to be unique - change the base type if you want to support multiple results - /// - public class CustomerByNameSpec : SingleResultSpecification + public CustomerByNameSpec(string name) { - public CustomerByNameSpec(string name) - { - Query.Where(x => x.Name == name) - .OrderBy(x => x.Name) - .ThenByDescending(x => x.Address); - } + Query.Where(x => x.Name == name) + .OrderBy(x => x.Name) + .ThenByDescending(x => x.Address); } } diff --git a/sample/Ardalis.SampleApp.Core/Specifications/CustomerByNameWithStoresSpec.cs b/sample/Ardalis.SampleApp.Core/Specifications/CustomerByNameWithStoresSpec.cs index 844eb23c..d90de7de 100644 --- a/sample/Ardalis.SampleApp.Core/Specifications/CustomerByNameWithStoresSpec.cs +++ b/sample/Ardalis.SampleApp.Core/Specifications/CustomerByNameWithStoresSpec.cs @@ -1,18 +1,17 @@ using Ardalis.SampleApp.Core.Entities.CustomerAggregate; using Ardalis.Specification; -namespace Ardalis.SampleApp.Core.Specifications +namespace Ardalis.SampleApp.Core.Specifications; + +/// +/// This specification expects customer names to be unique - change the base type if you want to support multiple results +/// +public class CustomerByNameWithStoresSpec : SingleResultSpecification { - /// - /// This specification expects customer names to be unique - change the base type if you want to support multiple results - /// - public class CustomerByNameWithStoresSpec : SingleResultSpecification + public CustomerByNameWithStoresSpec(string name) { - public CustomerByNameWithStoresSpec(string name) - { - Query.Where(x => x.Name == name) - .Include(x => x.Stores) - .EnableCache(nameof(CustomerByNameWithStoresSpec), name); - } + Query.Where(x => x.Name == name) + .Include(x => x.Stores) + .EnableCache(nameof(CustomerByNameWithStoresSpec), name); } } diff --git a/sample/Ardalis.SampleApp.Core/Specifications/CustomerSpec.cs b/sample/Ardalis.SampleApp.Core/Specifications/CustomerSpec.cs index d6184c55..0bb3420d 100644 --- a/sample/Ardalis.SampleApp.Core/Specifications/CustomerSpec.cs +++ b/sample/Ardalis.SampleApp.Core/Specifications/CustomerSpec.cs @@ -2,33 +2,32 @@ using Ardalis.SampleApp.Core.Specifications.Filters; using Ardalis.Specification; -namespace Ardalis.SampleApp.Core.Specifications +namespace Ardalis.SampleApp.Core.Specifications; + +/// +/// This specification expects 0 to many results +/// +public class CustomerSpec : Specification { - /// - /// This specification expects 0 to many results - /// - public class CustomerSpec : Specification + public CustomerSpec(CustomerFilter filter) { - public CustomerSpec(CustomerFilter filter) - { - Query.OrderBy(x => x.Name) - .ThenByDescending(x => x.Address); + Query.OrderBy(x => x.Name) + .ThenByDescending(x => x.Address); - if (filter.LoadChildren) - Query.Include(x => x.Stores); + if (filter.LoadChildren) + Query.Include(x => x.Stores); - if (filter.IsPagingEnabled) - Query.Skip(PaginationHelper.CalculateSkip(filter)) - .Take(PaginationHelper.CalculateTake(filter)); + if (filter.IsPagingEnabled) + Query.Skip(PaginationHelper.CalculateSkip(filter)) + .Take(PaginationHelper.CalculateTake(filter)); - if (!string.IsNullOrEmpty(filter.Name)) - Query.Where(x => x.Name == filter.Name); + 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.Email)) + Query.Where(x => x.Email == filter.Email); - if (!string.IsNullOrEmpty(filter.Address)) - Query.Search(x => x.Address, "%" + filter.Address + "%"); - } + if (!string.IsNullOrEmpty(filter.Address)) + Query.Search(x => x.Address, "%" + filter.Address + "%"); } } diff --git a/sample/Ardalis.SampleApp.Core/Specifications/Filters/BaseFilter.cs b/sample/Ardalis.SampleApp.Core/Specifications/Filters/BaseFilter.cs index 5cbae747..3f46e75f 100644 --- a/sample/Ardalis.SampleApp.Core/Specifications/Filters/BaseFilter.cs +++ b/sample/Ardalis.SampleApp.Core/Specifications/Filters/BaseFilter.cs @@ -1,15 +1,10 @@ -using System; -using System.Collections.Generic; -using System.Text; +namespace Ardalis.SampleApp.Core.Specifications.Filters; -namespace Ardalis.SampleApp.Core.Specifications.Filters +public class BaseFilter { - public class BaseFilter - { - public bool LoadChildren { get; set; } - public bool IsPagingEnabled { get; set; } + public bool LoadChildren { get; set; } + public bool IsPagingEnabled { get; set; } - public int Page { get; set; } - public int PageSize { get; set; } - } + public int Page { get; set; } + public int PageSize { get; set; } } diff --git a/sample/Ardalis.SampleApp.Core/Specifications/Filters/CustomerFilter.cs b/sample/Ardalis.SampleApp.Core/Specifications/Filters/CustomerFilter.cs index 10c4a13d..458f85ee 100644 --- a/sample/Ardalis.SampleApp.Core/Specifications/Filters/CustomerFilter.cs +++ b/sample/Ardalis.SampleApp.Core/Specifications/Filters/CustomerFilter.cs @@ -1,13 +1,8 @@ -using System; -using System.Collections.Generic; -using System.Text; +namespace Ardalis.SampleApp.Core.Specifications.Filters; -namespace Ardalis.SampleApp.Core.Specifications.Filters +public class CustomerFilter : BaseFilter { - public class CustomerFilter : BaseFilter - { - public string Name { get; set; } - public string Email { get; set; } - public string Address { get; set; } - } + public string Name { get; set; } + public string Email { get; set; } + public string Address { get; set; } } diff --git a/sample/Ardalis.SampleApp.Core/Specifications/PaginationHelper.cs b/sample/Ardalis.SampleApp.Core/Specifications/PaginationHelper.cs index 19dac0e9..ba7ad829 100644 --- a/sample/Ardalis.SampleApp.Core/Specifications/PaginationHelper.cs +++ b/sample/Ardalis.SampleApp.Core/Specifications/PaginationHelper.cs @@ -1,30 +1,29 @@ using Ardalis.SampleApp.Core.Specifications.Filters; -namespace Ardalis.SampleApp.Core.Specifications +namespace Ardalis.SampleApp.Core.Specifications; + +public static class PaginationHelper { - public static class PaginationHelper - { - public static int DefaultPage => 1; - public static int DefaultPageSize => 10; + public static int DefaultPage => 1; + public static int DefaultPageSize => 10; - public static int CalculateTake(int pageSize) - { - return pageSize <= 0 ? DefaultPageSize : pageSize; - } - public static int CalculateSkip(int pageSize, int page) - { - page = page <= 0 ? DefaultPage : page; + public static int CalculateTake(int pageSize) + { + return pageSize <= 0 ? DefaultPageSize : pageSize; + } + public static int CalculateSkip(int pageSize, int page) + { + page = page <= 0 ? DefaultPage : page; - return CalculateTake(pageSize) * (page - 1); - } + return CalculateTake(pageSize) * (page - 1); + } - public static int CalculateTake(BaseFilter baseFilter) - { - return CalculateTake(baseFilter.PageSize); - } - public static int CalculateSkip(BaseFilter baseFilter) - { - return CalculateSkip(baseFilter.PageSize, baseFilter.Page); - } + public static int CalculateTake(BaseFilter baseFilter) + { + return CalculateTake(baseFilter.PageSize); + } + public static int CalculateSkip(BaseFilter baseFilter) + { + return CalculateSkip(baseFilter.PageSize, baseFilter.Page); } } diff --git a/sample/Ardalis.SampleApp.Infrastructure/Ardalis.SampleApp.Infrastructure.csproj b/sample/Ardalis.SampleApp.Infrastructure/Ardalis.SampleApp.Infrastructure.csproj index 14b55fac..7bf8883f 100644 --- a/sample/Ardalis.SampleApp.Infrastructure/Ardalis.SampleApp.Infrastructure.csproj +++ b/sample/Ardalis.SampleApp.Infrastructure/Ardalis.SampleApp.Infrastructure.csproj @@ -2,6 +2,7 @@ net6.0 + 11.0 diff --git a/sample/Ardalis.SampleApp.Infrastructure/Data/CachedCustomerRepository.cs b/sample/Ardalis.SampleApp.Infrastructure/Data/CachedCustomerRepository.cs index 7775098d..49ecf3c0 100644 --- a/sample/Ardalis.SampleApp.Infrastructure/Data/CachedCustomerRepository.cs +++ b/sample/Ardalis.SampleApp.Infrastructure/Data/CachedCustomerRepository.cs @@ -1,11 +1,11 @@ -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; -using Ardalis.SampleApp.Core.Interfaces; +using Ardalis.SampleApp.Core.Interfaces; using Ardalis.Specification; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; namespace Ardalis.SampleApp.Infrastructure.Data; @@ -15,7 +15,7 @@ public class CachedRepository : IReadRepository where T : class, IAggregat private readonly IMemoryCache _cache; private readonly ILogger> _logger; private readonly MyRepository _sourceRepository; - private MemoryCacheEntryOptions _cacheOptions; + private readonly MemoryCacheEntryOptions _cacheOptions; public CachedRepository(IMemoryCache cache, ILogger> logger, @@ -76,16 +76,16 @@ public Task GetByIdAsync(TId id, CancellationToken cancellationToken = d } /// - public Task FirstOrDefaultAsync(ISpecification specification, CancellationToken cancellationToken = default) + public Task FirstOrDefaultAsync(ISpecification specification, CancellationToken cancellationToken = default) { if (specification.CacheEnabled) { - string key = $"{specification.CacheKey}-GetBySpecAsync"; - _logger.LogInformation("Checking cache for " + key); + var key = $"{specification.CacheKey}-GetBySpecAsync"; + _logger.LogInformation("Checking cache for {cache_key}", key); return _cache.GetOrCreate(key, entry => { entry.SetOptions(_cacheOptions); - _logger.LogWarning("Fetching source data for " + key); + _logger.LogWarning("Fetching source data for {cache_key}", key); return _sourceRepository.FirstOrDefaultAsync(specification, cancellationToken); }); } @@ -99,19 +99,19 @@ public Task GetBySpecAsync(ISpecification specific } /// - public virtual async Task FirstOrDefaultAsync(ISpecification specification, CancellationToken cancellationToken = default) + public virtual async Task FirstOrDefaultAsync(ISpecification specification, CancellationToken cancellationToken = default) { return await _sourceRepository.FirstOrDefaultAsync(specification, cancellationToken); } /// - public virtual async Task SingleOrDefaultAsync(ISingleResultSpecification specification, CancellationToken cancellationToken = default) + public virtual async Task SingleOrDefaultAsync(ISingleResultSpecification specification, CancellationToken cancellationToken = default) { return await _sourceRepository.SingleOrDefaultAsync(specification, cancellationToken); } /// - public virtual async Task SingleOrDefaultAsync(ISingleResultSpecification specification, CancellationToken cancellationToken = default) + public virtual async Task SingleOrDefaultAsync(ISingleResultSpecification specification, CancellationToken cancellationToken = default) { return await _sourceRepository.SingleOrDefaultAsync(specification, cancellationToken); } @@ -119,7 +119,7 @@ public Task GetBySpecAsync(ISpecification specific /// public Task> ListAsync(CancellationToken cancellationToken = default) { - string key = $"{nameof(T)}-ListAsync"; + var key = $"{nameof(T)}-ListAsync"; return _cache.GetOrCreate(key, entry => { entry.SetOptions(_cacheOptions); @@ -132,12 +132,12 @@ public Task> ListAsync(ISpecification specification, CancellationToke { if (specification.CacheEnabled) { - string key = $"{specification.CacheKey}-ListAsync"; - _logger.LogInformation("Checking cache for " + key); + var key = $"{specification.CacheKey}-ListAsync"; + _logger.LogInformation("Checking cache for {cache_key}", key); return _cache.GetOrCreate(key, entry => { entry.SetOptions(_cacheOptions); - _logger.LogWarning("Fetching source data for " + key); + _logger.LogWarning("Fetching source data for {cache_key}", key); return _sourceRepository.ListAsync(specification, cancellationToken); }); } diff --git a/sample/Ardalis.SampleApp.Infrastructure/Data/CustomerRepository.cs b/sample/Ardalis.SampleApp.Infrastructure/Data/CustomerRepository.cs index e30926ee..be5ae5fc 100644 --- a/sample/Ardalis.SampleApp.Infrastructure/Data/CustomerRepository.cs +++ b/sample/Ardalis.SampleApp.Infrastructure/Data/CustomerRepository.cs @@ -1,10 +1,10 @@ -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Ardalis.SampleApp.Core.Entities.CustomerAggregate; +using Ardalis.SampleApp.Core.Entities.CustomerAggregate; using Ardalis.SampleApp.Core.Interfaces; using Ardalis.SampleApp.Infrastructure.DataAccess; using Microsoft.EntityFrameworkCore; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; namespace Ardalis.SampleApp.Infrastructure.Data; diff --git a/sample/Ardalis.SampleApp.Infrastructure/DataAccess/Configurations/CustomerConfiguration.cs b/sample/Ardalis.SampleApp.Infrastructure/DataAccess/Configurations/CustomerConfiguration.cs index 7ccd7c8b..d2d6a753 100644 --- a/sample/Ardalis.SampleApp.Infrastructure/DataAccess/Configurations/CustomerConfiguration.cs +++ b/sample/Ardalis.SampleApp.Infrastructure/DataAccess/Configurations/CustomerConfiguration.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; -using Ardalis.SampleApp.Core.Entities.CustomerAggregate; +using Ardalis.SampleApp.Core.Entities.CustomerAggregate; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; diff --git a/sample/Ardalis.SampleApp.Infrastructure/DataAccess/Configurations/StoreConfiguration.cs b/sample/Ardalis.SampleApp.Infrastructure/DataAccess/Configurations/StoreConfiguration.cs index d847a1f2..bfe2efef 100644 --- a/sample/Ardalis.SampleApp.Infrastructure/DataAccess/Configurations/StoreConfiguration.cs +++ b/sample/Ardalis.SampleApp.Infrastructure/DataAccess/Configurations/StoreConfiguration.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; -using Ardalis.SampleApp.Core.Entities.CustomerAggregate; +using Ardalis.SampleApp.Core.Entities.CustomerAggregate; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; diff --git a/sample/Ardalis.SampleApp.Infrastructure/DataAccess/SampleDbContextSeed.cs b/sample/Ardalis.SampleApp.Infrastructure/DataAccess/SampleDbContextSeed.cs index ed0f400d..74c16677 100644 --- a/sample/Ardalis.SampleApp.Infrastructure/DataAccess/SampleDbContextSeed.cs +++ b/sample/Ardalis.SampleApp.Infrastructure/DataAccess/SampleDbContextSeed.cs @@ -1,9 +1,7 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading.Tasks; -using Ardalis.SampleApp.Core.Entities.Seeds; +using Ardalis.SampleApp.Core.Entities.Seeds; using Microsoft.EntityFrameworkCore; +using System; +using System.Threading.Tasks; namespace Ardalis.SampleApp.Infrastructure.DataAccess; diff --git a/sample/Ardalis.SampleApp.Web/Ardalis.SampleApp.Web.csproj b/sample/Ardalis.SampleApp.Web/Ardalis.SampleApp.Web.csproj index bf4fb1db..ecd94194 100644 --- a/sample/Ardalis.SampleApp.Web/Ardalis.SampleApp.Web.csproj +++ b/sample/Ardalis.SampleApp.Web/Ardalis.SampleApp.Web.csproj @@ -1,7 +1,8 @@ - + net6.0 + 11.0 @@ -20,4 +21,9 @@ + + + 1701;1702;1591;1573;0612 + + diff --git a/sample/Ardalis.SampleApp.Web/AutomapperMaps.cs b/sample/Ardalis.SampleApp.Web/AutomapperMaps.cs index 28f86310..63dacf0a 100644 --- a/sample/Ardalis.SampleApp.Web/AutomapperMaps.cs +++ b/sample/Ardalis.SampleApp.Web/AutomapperMaps.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Ardalis.SampleApp.Core.Entities.CustomerAggregate; +using Ardalis.SampleApp.Core.Entities.CustomerAggregate; using Ardalis.SampleApp.Core.Specifications.Filters; using Ardalis.SampleApp.Web.Models; using AutoMapper; diff --git a/sample/Ardalis.SampleApp.Web/Controllers/CustomersController.cs b/sample/Ardalis.SampleApp.Web/Controllers/CustomersController.cs index 967a480d..b071d4f6 100644 --- a/sample/Ardalis.SampleApp.Web/Controllers/CustomersController.cs +++ b/sample/Ardalis.SampleApp.Web/Controllers/CustomersController.cs @@ -1,8 +1,8 @@ -using System.Collections.Generic; -using System.Threading.Tasks; -using Ardalis.SampleApp.Web.Interfaces; +using Ardalis.SampleApp.Web.Interfaces; using Ardalis.SampleApp.Web.Models; using Microsoft.AspNetCore.Mvc; +using System.Collections.Generic; +using System.Threading.Tasks; namespace Ardalis.SampleApp.Web.Controllers; diff --git a/sample/Ardalis.SampleApp.Web/Interfaces/ICustomerUiService.cs b/sample/Ardalis.SampleApp.Web/Interfaces/ICustomerUiService.cs index 7dcff9ec..a716e865 100644 --- a/sample/Ardalis.SampleApp.Web/Interfaces/ICustomerUiService.cs +++ b/sample/Ardalis.SampleApp.Web/Interfaces/ICustomerUiService.cs @@ -1,6 +1,6 @@ -using System.Collections.Generic; +using Ardalis.SampleApp.Web.Models; +using System.Collections.Generic; using System.Threading.Tasks; -using Ardalis.SampleApp.Web.Models; namespace Ardalis.SampleApp.Web.Interfaces; diff --git a/sample/Ardalis.SampleApp.Web/Models/BaseFilterDto.cs b/sample/Ardalis.SampleApp.Web/Models/BaseFilterDto.cs index e66cb42d..b969e098 100644 --- a/sample/Ardalis.SampleApp.Web/Models/BaseFilterDto.cs +++ b/sample/Ardalis.SampleApp.Web/Models/BaseFilterDto.cs @@ -1,9 +1,5 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; +using System.ComponentModel; using System.Text.Json.Serialization; -using System.Threading.Tasks; namespace Ardalis.SampleApp.Web.Models; diff --git a/sample/Ardalis.SampleApp.Web/Models/CustomerDto.cs b/sample/Ardalis.SampleApp.Web/Models/CustomerDto.cs index ef030aed..8658881f 100644 --- a/sample/Ardalis.SampleApp.Web/Models/CustomerDto.cs +++ b/sample/Ardalis.SampleApp.Web/Models/CustomerDto.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; +using System.Collections.Generic; namespace Ardalis.SampleApp.Web.Models; diff --git a/sample/Ardalis.SampleApp.Web/Models/CustomerFilterDto.cs b/sample/Ardalis.SampleApp.Web/Models/CustomerFilterDto.cs index c2bcc00c..af2afd4e 100644 --- a/sample/Ardalis.SampleApp.Web/Models/CustomerFilterDto.cs +++ b/sample/Ardalis.SampleApp.Web/Models/CustomerFilterDto.cs @@ -1,11 +1,4 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; -using System.Text.Json.Serialization; -using System.Threading.Tasks; - -namespace Ardalis.SampleApp.Web.Models; +namespace Ardalis.SampleApp.Web.Models; public class CustomerFilterDto : BaseFilterDto { diff --git a/sample/Ardalis.SampleApp.Web/Models/StoreDto.cs b/sample/Ardalis.SampleApp.Web/Models/StoreDto.cs index cfd8cdb5..340fa33e 100644 --- a/sample/Ardalis.SampleApp.Web/Models/StoreDto.cs +++ b/sample/Ardalis.SampleApp.Web/Models/StoreDto.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Ardalis.SampleApp.Web.Models; +namespace Ardalis.SampleApp.Web.Models; public class StoreDto { diff --git a/sample/Ardalis.SampleApp.Web/Pages/Index.cshtml.cs b/sample/Ardalis.SampleApp.Web/Pages/Index.cshtml.cs index 42678637..b580dc45 100644 --- a/sample/Ardalis.SampleApp.Web/Pages/Index.cshtml.cs +++ b/sample/Ardalis.SampleApp.Web/Pages/Index.cshtml.cs @@ -1,11 +1,11 @@ -using System.Collections.Generic; -using System.Diagnostics; -using System.Threading.Tasks; -using Ardalis.SampleApp.Core.Entities.CustomerAggregate; +using Ardalis.SampleApp.Core.Entities.CustomerAggregate; using Ardalis.SampleApp.Core.Interfaces; using Ardalis.SampleApp.Core.Specifications; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.Extensions.Logging; +using System.Collections.Generic; +using System.Diagnostics; +using System.Threading.Tasks; namespace Ardalis.SampleApp.Web.Pages; diff --git a/sample/Ardalis.SampleApp.Web/Program.cs b/sample/Ardalis.SampleApp.Web/Program.cs index 42c02c07..419ca9e8 100644 --- a/sample/Ardalis.SampleApp.Web/Program.cs +++ b/sample/Ardalis.SampleApp.Web/Program.cs @@ -1,10 +1,10 @@ -using System; -using System.Threading.Tasks; -using Ardalis.SampleApp.Infrastructure.DataAccess; +using Ardalis.SampleApp.Infrastructure.DataAccess; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; +using System; +using System.Threading.Tasks; namespace Ardalis.SampleApp.Web; diff --git a/sample/Ardalis.SampleApp.Web/Services/CustomerUiService.cs b/sample/Ardalis.SampleApp.Web/Services/CustomerUiService.cs index 018be348..cd4a9281 100644 --- a/sample/Ardalis.SampleApp.Web/Services/CustomerUiService.cs +++ b/sample/Ardalis.SampleApp.Web/Services/CustomerUiService.cs @@ -1,6 +1,4 @@ -using System.Collections.Generic; -using System.Threading.Tasks; -using Ardalis.GuardClauses; +using Ardalis.GuardClauses; using Ardalis.SampleApp.Core.Entities.CustomerAggregate; using Ardalis.SampleApp.Core.Interfaces; using Ardalis.SampleApp.Core.Specifications; @@ -8,6 +6,8 @@ using Ardalis.SampleApp.Web.Interfaces; using Ardalis.SampleApp.Web.Models; using AutoMapper; +using System.Collections.Generic; +using System.Threading.Tasks; namespace Ardalis.SampleApp.Web.Services; From 7fc23d2c5d718ad3ea4becb9a29360242f6f08d7 Mon Sep 17 00:00:00 2001 From: Fati Iseni Date: Fri, 21 Jul 2023 14:22:57 +0200 Subject: [PATCH 2/3] Exclude UniTest project from code coverage. --- .../Ardalis.Specification.UnitTests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Ardalis.Specification.UnitTests.csproj b/Specification/tests/Ardalis.Specification.UnitTests/Ardalis.Specification.UnitTests.csproj index 5ec1e566..21d6c491 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Ardalis.Specification.UnitTests.csproj +++ b/Specification/tests/Ardalis.Specification.UnitTests/Ardalis.Specification.UnitTests.csproj @@ -25,7 +25,7 @@ - + From 1ad673ed903d56f60277236b7e2deb4170e2ce7a Mon Sep 17 00:00:00 2001 From: Fati Iseni Date: Fri, 21 Jul 2023 17:52:34 +0200 Subject: [PATCH 3/3] Applied 4 spaces for indent size. --- .editorconfig | 5 +- .../Evaluators/AsNoTrackingEvaluator.cs | 20 +- .../Evaluators/IncludeEvaluator.cs | 42 +- .../Evaluators/OrderEvaluator.cs | 156 +-- .../Evaluators/SearchEvaluator.cs | 20 +- .../Evaluators/SpecificationEvaluator.cs | 88 +- .../Extensions/DbSetExtensions.cs | 80 +- .../Extensions/IncludeExtensions.cs | 80 +- .../Extensions/ParameterReplacerVisitor.cs | 22 +- .../Extensions/SearchExtension.cs | 72 +- .../RepositoryBaseOfT.cs | 382 +++---- .../Configurations/AddressConfiguration.cs | 10 +- .../Configurations/CompanyConfiguration.cs | 18 +- .../Configurations/CountryConfiguration.cs | 10 +- .../Configurations/ProductConfiguration.cs | 10 +- .../Configurations/StoreConfiguration.cs | 14 +- .../Fixture/DbInitializer.cs | 20 +- .../Fixture/IntegrationTestBase.cs | 18 +- .../Fixture/RepositoryOfT.cs | 10 +- .../Fixture/SharedDatabaseFixture.cs | 50 +- .../Fixture/TestDbContext.cs | 42 +- .../RepositoryOfT_AnyAsync.cs | 38 +- .../RepositoryOfT_GetById.cs | 30 +- .../RepositoryOfT_GetBySpec.cs | 178 ++-- .../RepositoryOfT_ListAsync.cs | 294 +++--- .../CachedReadConcurrentDictionary.cs | 376 +++---- .../ContextFactoryRepositoryBaseOfT.cs | 438 ++++---- .../EFRepositoryFactory.cs | 30 +- .../Evaluators/AsNoTrackingEvaluator.cs | 20 +- ...TrackingWithIdentityResolutionEvaluator.cs | 20 +- .../Evaluators/AsSplitQueryEvaluator.cs | 20 +- .../Evaluators/AsTrackingEvaluator.cs | 20 +- .../Evaluators/IgnoreQueryFiltersEvaluator.cs | 20 +- .../Evaluators/IncludeEvaluator.cs | 298 +++--- .../Evaluators/SearchEvaluator.cs | 20 +- .../Evaluators/SpecificationEvaluator.cs | 102 +- .../Extensions/DbSetExtensions.cs | 80 +- .../Extensions/ParameterReplacerVisitor.cs | 22 +- .../Extensions/SearchExtension.cs | 86 +- .../IRepositoryFactory.cs | 10 +- .../RepositoryBaseOfT.cs | 388 +++---- .../ContextFactoryRepositoryBaseOfTTests.cs | 202 ++-- .../EFRepositoryFactoryTests.cs | 214 ++-- .../Fixture/ContextFactoryRepositoryOfT.cs | 14 +- .../Fixture/GetCompanyWithStoresSpec.cs | 8 +- .../Fixture/IntegrationTestBase.cs | 18 +- .../Fixture/LoggerFactoryProvider.cs | 10 +- .../Fixture/RepositoryOfT.cs | 16 +- .../Fixture/SharedDatabaseFixture.cs | 112 +- .../Fixture/TestDbContext.cs | 46 +- .../RepositoryOfT_AnyAsync.cs | 50 +- .../RepositoryOfT_AsAsyncEnumerable.cs | 64 +- .../RepositoryOfT_GetById.cs | 42 +- .../RepositoryOfT_GetBySpec.cs | 190 ++-- .../RepositoryOfT_ListAsync.cs | 350 +++---- .../Builder/CacheSpecificationBuilder.cs | 22 +- .../Builder/ICacheSpecificationBuilder.cs | 2 +- .../IIncludableSpecificationBuilder.cs | 2 +- .../Builder/IOrderedSpecificationBuilder.cs | 2 +- .../Builder/ISpecificationBuilder.cs | 4 +- .../Builder/IncludableBuilderExtensions.cs | 76 +- .../Builder/IncludableSpecificationBuilder.cs | 22 +- .../Builder/OrderedBuilderExtensions.cs | 72 +- .../Builder/OrderedSpecificationBuilder.cs | 22 +- .../Builder/SpecificationBuilder.cs | 22 +- .../Builder/SpecificationBuilderExtensions.cs | 962 +++++++++--------- .../Evaluators/IEvaluator.cs | 4 +- .../Evaluators/IInMemoryEvaluator.cs | 2 +- .../IInMemorySpecificationEvaluator.cs | 4 +- .../Evaluators/ISpecificationEvaluator.cs | 32 +- .../InMemorySpecificationEvaluator.cs | 82 +- .../Evaluators/OrderEvaluator.cs | 142 +-- .../Evaluators/PaginationEvaluator.cs | 52 +- .../Evaluators/SearchEvaluator.cs | 18 +- .../Evaluators/SearchExtension.cs | 266 ++--- .../Evaluators/WhereEvaluator.cs | 34 +- .../ConcurrentSelectorsException.cs | 18 +- .../DuplicateOrderChainException.cs | 18 +- .../Exceptions/DuplicateSkipException.cs | 18 +- .../Exceptions/DuplicateTakeException.cs | 18 +- .../InvalidSearchPatternException.cs | 18 +- .../Exceptions/SelectorNotFoundException.cs | 18 +- .../Expressions/IncludeExpressionInfo.cs | 136 +-- .../Expressions/OrderExpressionInfo.cs | 64 +- .../Expressions/SearchExpressionInfo.cs | 82 +- .../Expressions/WhereExpressionInfo.cs | 40 +- .../src/Ardalis.Specification/IEntity.cs | 2 +- .../IReadRepositoryBase.cs | 324 +++--- .../Ardalis.Specification/IRepositoryBase.cs | 98 +- .../Ardalis.Specification/ISpecification.cs | 254 ++--- .../Ardalis.Specification/IncludeTypeEnum.cs | 4 +- .../Ardalis.Specification/OrderTypeEnum.cs | 8 +- .../Ardalis.Specification/Specification.cs | 164 +-- .../Validators/ISpecificationValidator.cs | 2 +- .../Validators/IValidator.cs | 2 +- .../Validators/SearchValidator.cs | 18 +- .../Validators/SpecificationValidator.cs | 42 +- .../Validators/WhereValidator.cs | 18 +- ...IncludableBuilderExtensions_ThenInclude.cs | 62 +- .../OrderedBuilderExtensions_ThenBy.cs | 48 +- ...deredBuilderExtensions_ThenByDescending.cs | 48 +- ...ificationBuilderExtensions_AsNoTracking.cs | 48 +- ...ions_AsNoTrackingWithIdentityResolution.cs | 48 +- ...ificationBuilderExtensions_AsSplitQuery.cs | 36 +- ...ecificationBuilderExtensions_AsTracking.cs | 48 +- ...ionBuilderExtensions_IgnoreQueryFilters.cs | 36 +- .../SpecificationBuilderExtensions_Include.cs | 38 +- ...ficationBuilderExtensions_IncludeString.cs | 40 +- .../SpecificationBuilderExtensions_OrderBy.cs | 38 +- ...tionBuilderExtensions_OrderByDescending.cs | 38 +- ...nBuilderExtensions_PostProcessingAction.cs | 48 +- .../SpecificationBuilderExtensions_Search.cs | 100 +- .../SpecificationBuilderExtensions_Select.cs | 24 +- ...ecificationBuilderExtensions_SelectMany.cs | 24 +- .../SpecificationBuilderExtensions_Skip.cs | 56 +- .../SpecificationBuilderExtensions_Take.cs | 42 +- .../SpecificationBuilderExtensions_Where.cs | 48 +- .../InMemorySpecificationEvaluatorTests.cs | 204 ++-- .../SearchEvaluator_Evaluate.cs | 44 +- .../EvaluatorTests/SearchExtension_Like.cs | 162 +-- .../ConcurrentSelectorsExceptionTests.cs | 28 +- .../DuplicateOrderChainExceptionTests.cs | 28 +- .../DuplicateSkipExceptionTests.cs | 28 +- .../DuplicateTakeExceptionTests.cs | 28 +- .../InvalidSearchPatternExceptionTests.cs | 30 +- .../SelectorNotFoundExceptionTests.cs | 28 +- .../Fixture/Entities/Address.cs | 16 +- .../Fixture/Entities/Company.cs | 10 +- .../Fixture/Entities/Country.cs | 6 +- .../Fixture/Entities/Product.cs | 8 +- .../Fixture/Entities/Seeds/AddressSeed.cs | 30 +- .../Fixture/Entities/Seeds/CompanySeed.cs | 14 +- .../Fixture/Entities/Seeds/CountrySeed.cs | 30 +- .../Fixture/Entities/Seeds/ProductSeed.cs | 44 +- .../Fixture/Entities/Seeds/StoreSeed.cs | 110 +- .../Fixture/Entities/Store.cs | 24 +- .../Fixture/Specs/CompanyByIdAsSplitQuery.cs | 14 +- .../Fixture/Specs/CompanyByIdAsTrackedSpec.cs | 8 +- .../Specs/CompanyByIdAsUntrackedSpec.cs | 8 +- ...IdAsUntrackedWithIdentityResolutionSpec.cs | 8 +- .../Specs/CompanyByIdIgnoreQueryFilters.cs | 8 +- ...ByIdIncludeStoresThenIncludeAddressSpec.cs | 12 +- ...yIdIncludeStoresThenIncludeProductsSpec.cs | 12 +- .../Fixture/Specs/CompanyByIdSpec.cs | 8 +- ...ompanyByIdWithAsNoTrackingAsTrackedSpec.cs | 8 +- ...ompanyByIdWithAsTrackingAsUntrackedSpec.cs | 8 +- ...ngAsUntrackedWithIdentityResolutionSpec.cs | 8 +- .../Specs/CompanyByIdWithFalseConditions.cs | 42 +- ...nyByIdWithFalseConditionsForInnerChains.cs | 44 +- .../Fixture/Specs/StoreByIdAndNameSpec.cs | 10 +- .../StoreByIdIncludeAddressAndProductsSpec.cs | 12 +- .../Specs/StoreByIdIncludeAddressSpec.cs | 10 +- ...ompanyAndCountryAndStoresForCompanySpec.cs | 12 +- .../Specs/StoreByIdIncludeProductsSpec.cs | 10 +- ...StoreByIdIncludeProductsUsingStringSpec.cs | 10 +- .../Specs/StoreByIdSearchByNameAndCitySpec.cs | 12 +- .../Specs/StoreByIdSearchByNameOrCitySpec.cs | 12 +- .../Fixture/Specs/StoreByIdSpec.cs | 8 +- .../Fixture/Specs/StoreDuplicateSkipSpec.cs | 10 +- .../Fixture/Specs/StoreDuplicateTakeSpec.cs | 10 +- .../Fixture/Specs/StoreEmptySpec.cs | 6 +- .../Fixture/Specs/StoreNamesEmptySpec.cs | 6 +- .../Fixture/Specs/StoreNamesPaginatedSpec.cs | 14 +- .../Fixture/Specs/StoreNamesSpec.cs | 8 +- .../StoreNamesWithPostProcessingActionSpec.cs | 10 +- .../Specs/StoreProductNamesEmptySpec.cs | 6 +- .../Fixture/Specs/StoreProductNamesSpec.cs | 8 +- .../Specs/StoreSearchByNameAndCitySpec.cs | 10 +- .../Specs/StoreSearchByNameOrCitySpec.cs | 10 +- .../Fixture/Specs/StoreSearchByNameSpec.cs | 8 +- .../StoreWithPostProcessingActionSpec.cs | 8 +- .../StoresByCompanyOrderedDescByNameSpec.cs | 10 +- ...ompanyOrderedDescByNameThenByDescIdSpec.cs | 12 +- ...sByCompanyOrderedDescByNameThenByIdSpec.cs | 12 +- ...ByCompanyPaginatedOrderedDescByNameSpec.cs | 14 +- .../Specs/StoresByCompanyPaginatedSpec.cs | 14 +- .../Fixture/Specs/StoresByIdListSpec.cs | 8 +- .../StoresOrderedDescendingByNameSpec.cs | 8 +- .../Fixture/Specs/StoresOrderedSpecByName.cs | 8 +- .../Specs/StoresOrderedTwoChainsSpec.cs | 10 +- .../Fixture/Specs/StoresPaginatedSpec.cs | 12 +- .../CompanyIncludeFilteredStoresSpec.cs | 10 +- .../StoreIncludeAddressAndProductsSpec.cs | 10 +- .../StoreIncludeAddressSpec.cs | 8 +- ...reIncludeCompanyCountryDotSeparatedSpec.cs | 8 +- ...reIncludeCompanyThenCountryAsStringSpec.cs | 8 +- .../StoreIncludeCompanyThenCountrySpec.cs | 10 +- .../StoreIncludeCompanyThenNameSpec.cs | 10 +- .../StoreIncludeCompanyThenStoresSpec.cs | 12 +- .../StoreIncludeMethodOfNavigationSpec.cs | 8 +- .../StoreIncludeMethodSpec.cs | 8 +- .../StoreIncludeNameSpec.cs | 8 +- .../StoreIncludeProductsSpec.cs | 8 +- .../StoreWithFaultyIncludeSpec.cs | 8 +- .../IncludeExpressionInfoTests.cs | 84 +- .../SpecificationValidator_Tests.cs | 110 +- .../Entities/CustomerAggregate/Customer.cs | 64 +- .../Entities/CustomerAggregate/Store.cs | 20 +- .../Entities/Seeds/CustomerSeed.cs | 24 +- .../Interfaces/ICustomerRepository.cs | 4 +- .../Specifications/CustomerByNameSpec.cs | 12 +- .../CustomerByNameWithStoresSpec.cs | 12 +- .../Specifications/CustomerSpec.cs | 32 +- .../Specifications/Filters/BaseFilter.cs | 8 +- .../Specifications/Filters/CustomerFilter.cs | 6 +- .../Specifications/PaginationHelper.cs | 38 +- .../Data/CachedCustomerRepository.cs | 282 ++--- .../Data/CustomerRepository.cs | 24 +- .../Data/MyRepository.cs | 12 +- .../Configurations/CustomerConfiguration.cs | 14 +- .../Configurations/StoreConfiguration.cs | 10 +- .../DataAccess/SampleDbContext.cs | 22 +- .../DataAccess/SampleDbContextSeed.cs | 50 +- .../Migrations/20201102224526_SampleDB-v1.cs | 96 +- .../Ardalis.SampleApp.Web/AutomapperMaps.cs | 14 +- .../Controllers/CustomersController.cs | 48 +- .../Interfaces/ICustomerUiService.cs | 8 +- .../Models/BaseFilterDto.cs | 16 +- .../Models/CustomerDto.cs | 10 +- .../Models/CustomerFilterDto.cs | 6 +- .../Ardalis.SampleApp.Web/Models/StoreDto.cs | 6 +- .../Pages/Index.cshtml.cs | 36 +- sample/Ardalis.SampleApp.Web/Program.cs | 50 +- .../Services/CustomerUiService.cs | 66 +- sample/Ardalis.SampleApp.Web/Startup.cs | 64 +- 225 files changed, 5908 insertions(+), 5909 deletions(-) diff --git a/.editorconfig b/.editorconfig index d7f77f43..147fc4ef 100644 --- a/.editorconfig +++ b/.editorconfig @@ -19,7 +19,8 @@ indent_size = 2 # Code files [*.{cs,csx,vb,vbx}] -indent_size = 2 +indent_size = 4 +tab_width = 4 insert_final_newline = true charset = utf-8-bom ############################### @@ -123,8 +124,6 @@ dotnet_naming_rule.members_should_be_pascal_case.style = non_private_static_fiel dotnet_naming_symbols.all_members.applicable_kinds = * dotnet_naming_style.pascal_case_style.capitalization = pascal_case dotnet_style_operator_placement_when_wrapping = beginning_of_line -tab_width = 2 -end_of_line = crlf dotnet_style_prefer_simplified_boolean_expressions = true:suggestion dotnet_style_prefer_compound_assignment = true:warning dotnet_style_prefer_simplified_interpolation = true:warning diff --git a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Evaluators/AsNoTrackingEvaluator.cs b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Evaluators/AsNoTrackingEvaluator.cs index 7c9fdaf9..5f5b999c 100644 --- a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Evaluators/AsNoTrackingEvaluator.cs +++ b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Evaluators/AsNoTrackingEvaluator.cs @@ -5,18 +5,18 @@ namespace Ardalis.Specification.EntityFramework6; public class AsNoTrackingEvaluator : IEvaluator { - private AsNoTrackingEvaluator() { } - public static AsNoTrackingEvaluator Instance { get; } = new AsNoTrackingEvaluator(); + private AsNoTrackingEvaluator() { } + public static AsNoTrackingEvaluator Instance { get; } = new AsNoTrackingEvaluator(); - public bool IsCriteriaEvaluator { get; } = true; + public bool IsCriteriaEvaluator { get; } = true; - public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class - { - if (specification.AsNoTracking) + public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class { - query = query.AsNoTracking(); - } + if (specification.AsNoTracking) + { + query = query.AsNoTracking(); + } - return query; - } + return query; + } } diff --git a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Evaluators/IncludeEvaluator.cs b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Evaluators/IncludeEvaluator.cs index 61f7a237..a8f63885 100644 --- a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Evaluators/IncludeEvaluator.cs +++ b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Evaluators/IncludeEvaluator.cs @@ -5,30 +5,30 @@ namespace Ardalis.Specification.EntityFramework6; public class IncludeEvaluator : IEvaluator { - private IncludeEvaluator() { } - public static IncludeEvaluator Instance { get; } = new IncludeEvaluator(); + private IncludeEvaluator() { } + public static IncludeEvaluator Instance { get; } = new IncludeEvaluator(); - public bool IsCriteriaEvaluator { get; } = false; + public bool IsCriteriaEvaluator { get; } = false; - public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class - { - foreach (var includeString in specification.IncludeStrings) + public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class { - query = query.Include(includeString); - } + foreach (var includeString in specification.IncludeStrings) + { + query = query.Include(includeString); + } - foreach (var includeInfo in specification.IncludeExpressions) - { - if (includeInfo.Type == IncludeTypeEnum.Include) - { - query = query.Include(includeInfo); - } - else if (includeInfo.Type == IncludeTypeEnum.ThenInclude) - { - query = query.ThenInclude(includeInfo); - } - } + foreach (var includeInfo in specification.IncludeExpressions) + { + if (includeInfo.Type == IncludeTypeEnum.Include) + { + query = query.Include(includeInfo); + } + else if (includeInfo.Type == IncludeTypeEnum.ThenInclude) + { + query = query.ThenInclude(includeInfo); + } + } - return query; - } + return query; + } } diff --git a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Evaluators/OrderEvaluator.cs b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Evaluators/OrderEvaluator.cs index 12721da4..e75eb4f5 100644 --- a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Evaluators/OrderEvaluator.cs +++ b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Evaluators/OrderEvaluator.cs @@ -6,97 +6,97 @@ namespace Ardalis.Specification.EntityFramework6; public class OrderEvaluator : IEvaluator, IInMemoryEvaluator { - private OrderEvaluator() { } - public static OrderEvaluator Instance { get; } = new OrderEvaluator(); + private OrderEvaluator() { } + public static OrderEvaluator Instance { get; } = new OrderEvaluator(); - public bool IsCriteriaEvaluator { get; } = false; + public bool IsCriteriaEvaluator { get; } = false; - public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class - { - if (specification.OrderExpressions != null) + public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class { - if (specification.OrderExpressions.Count(x => x.OrderType == OrderTypeEnum.OrderBy - || x.OrderType == OrderTypeEnum.OrderByDescending) > 1) - { - throw new DuplicateOrderChainException(); - } - - IOrderedQueryable orderedQuery = null; - foreach (var orderExpression in specification.OrderExpressions) - { - if (orderExpression.OrderType == OrderTypeEnum.OrderBy) - { - orderedQuery = Queryable.OrderBy((dynamic)query, (dynamic)RemoveConvert(orderExpression.KeySelector)); - } - else if (orderExpression.OrderType == OrderTypeEnum.OrderByDescending) + if (specification.OrderExpressions != null) { - orderedQuery = Queryable.OrderByDescending((dynamic)query, (dynamic)RemoveConvert(orderExpression.KeySelector)); - } - else if (orderExpression.OrderType == OrderTypeEnum.ThenBy) - { - orderedQuery = Queryable.ThenBy((dynamic)orderedQuery, (dynamic)RemoveConvert(orderExpression.KeySelector)); - } - else if (orderExpression.OrderType == OrderTypeEnum.ThenByDescending) - { - orderedQuery = Queryable.ThenByDescending((dynamic)orderedQuery, (dynamic)RemoveConvert(orderExpression.KeySelector)); + if (specification.OrderExpressions.Count(x => x.OrderType == OrderTypeEnum.OrderBy + || x.OrderType == OrderTypeEnum.OrderByDescending) > 1) + { + throw new DuplicateOrderChainException(); + } + + IOrderedQueryable orderedQuery = null; + foreach (var orderExpression in specification.OrderExpressions) + { + if (orderExpression.OrderType == OrderTypeEnum.OrderBy) + { + orderedQuery = Queryable.OrderBy((dynamic)query, (dynamic)RemoveConvert(orderExpression.KeySelector)); + } + else if (orderExpression.OrderType == OrderTypeEnum.OrderByDescending) + { + orderedQuery = Queryable.OrderByDescending((dynamic)query, (dynamic)RemoveConvert(orderExpression.KeySelector)); + } + else if (orderExpression.OrderType == OrderTypeEnum.ThenBy) + { + orderedQuery = Queryable.ThenBy((dynamic)orderedQuery, (dynamic)RemoveConvert(orderExpression.KeySelector)); + } + else if (orderExpression.OrderType == OrderTypeEnum.ThenByDescending) + { + orderedQuery = Queryable.ThenByDescending((dynamic)orderedQuery, (dynamic)RemoveConvert(orderExpression.KeySelector)); + } + } + + if (orderedQuery != null) + { + query = orderedQuery; + } } - } - if (orderedQuery != null) - { - query = orderedQuery; - } + return query; } - return query; - } - - public IEnumerable Evaluate(IEnumerable query, ISpecification specification) - { - if (specification.OrderExpressions != null) + public IEnumerable Evaluate(IEnumerable query, ISpecification specification) { - if (specification.OrderExpressions.Count(x => x.OrderType == OrderTypeEnum.OrderBy - || x.OrderType == OrderTypeEnum.OrderByDescending) > 1) - { - throw new DuplicateOrderChainException(); - } - - IOrderedEnumerable orderedQuery = null; - foreach (var orderExpression in specification.OrderExpressions) - { - if (orderExpression.OrderType == OrderTypeEnum.OrderBy) + if (specification.OrderExpressions != null) { - orderedQuery = Queryable.OrderBy((dynamic)query, (dynamic)RemoveConvert(orderExpression.KeySelector)); - } - else if (orderExpression.OrderType == OrderTypeEnum.OrderByDescending) - { - orderedQuery = Queryable.OrderByDescending((dynamic)query, (dynamic)RemoveConvert(orderExpression.KeySelector)); - } - else if (orderExpression.OrderType == OrderTypeEnum.ThenBy) - { - orderedQuery = Queryable.ThenBy((dynamic)orderedQuery, (dynamic)RemoveConvert(orderExpression.KeySelector)); - } - else if (orderExpression.OrderType == OrderTypeEnum.ThenByDescending) - { - orderedQuery = Queryable.ThenByDescending((dynamic)orderedQuery, (dynamic)RemoveConvert(orderExpression.KeySelector)); + if (specification.OrderExpressions.Count(x => x.OrderType == OrderTypeEnum.OrderBy + || x.OrderType == OrderTypeEnum.OrderByDescending) > 1) + { + throw new DuplicateOrderChainException(); + } + + IOrderedEnumerable orderedQuery = null; + foreach (var orderExpression in specification.OrderExpressions) + { + if (orderExpression.OrderType == OrderTypeEnum.OrderBy) + { + orderedQuery = Queryable.OrderBy((dynamic)query, (dynamic)RemoveConvert(orderExpression.KeySelector)); + } + else if (orderExpression.OrderType == OrderTypeEnum.OrderByDescending) + { + orderedQuery = Queryable.OrderByDescending((dynamic)query, (dynamic)RemoveConvert(orderExpression.KeySelector)); + } + else if (orderExpression.OrderType == OrderTypeEnum.ThenBy) + { + orderedQuery = Queryable.ThenBy((dynamic)orderedQuery, (dynamic)RemoveConvert(orderExpression.KeySelector)); + } + else if (orderExpression.OrderType == OrderTypeEnum.ThenByDescending) + { + orderedQuery = Queryable.ThenByDescending((dynamic)orderedQuery, (dynamic)RemoveConvert(orderExpression.KeySelector)); + } + } + + if (orderedQuery != null) + { + query = orderedQuery; + } } - } - if (orderedQuery != null) - { - query = orderedQuery; - } + return query; } - return query; - } - - private LambdaExpression RemoveConvert(LambdaExpression source) - { - var body = source.Body; - while (body.NodeType == ExpressionType.Convert) - body = ((UnaryExpression)body).Operand; + private LambdaExpression RemoveConvert(LambdaExpression source) + { + var body = source.Body; + while (body.NodeType == ExpressionType.Convert) + body = ((UnaryExpression)body).Operand; - return Expression.Lambda(body, source.Parameters); - } + return Expression.Lambda(body, source.Parameters); + } } diff --git a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Evaluators/SearchEvaluator.cs b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Evaluators/SearchEvaluator.cs index 91279d04..20079770 100644 --- a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Evaluators/SearchEvaluator.cs +++ b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Evaluators/SearchEvaluator.cs @@ -4,18 +4,18 @@ namespace Ardalis.Specification.EntityFramework6; public class SearchEvaluator : IEvaluator { - private SearchEvaluator() { } - public static SearchEvaluator Instance { get; } = new SearchEvaluator(); + private SearchEvaluator() { } + public static SearchEvaluator Instance { get; } = new SearchEvaluator(); - public bool IsCriteriaEvaluator { get; } = true; + public bool IsCriteriaEvaluator { get; } = true; - public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class - { - foreach (var searchCriteria in specification.SearchCriterias.GroupBy(x => x.SearchGroup)) + public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class { - query = query.Search(searchCriteria); - } + foreach (var searchCriteria in specification.SearchCriterias.GroupBy(x => x.SearchGroup)) + { + query = query.Search(searchCriteria); + } - return query; - } + return query; + } } diff --git a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Evaluators/SpecificationEvaluator.cs b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Evaluators/SpecificationEvaluator.cs index 1c2c3b63..82b8d6e8 100644 --- a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Evaluators/SpecificationEvaluator.cs +++ b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Evaluators/SpecificationEvaluator.cs @@ -7,54 +7,54 @@ namespace Ardalis.Specification.EntityFramework6; /// public class SpecificationEvaluator : ISpecificationEvaluator { - // Will use singleton for default configuration. Yet, it can be instantiated if necessary, with default or provided evaluators. - public static SpecificationEvaluator Default { get; } = new SpecificationEvaluator(); + // Will use singleton for default configuration. Yet, it can be instantiated if necessary, with default or provided evaluators. + public static SpecificationEvaluator Default { get; } = new SpecificationEvaluator(); - protected List Evaluators { get; } = new List(); + protected List Evaluators { get; } = new List(); - public SpecificationEvaluator() - { - Evaluators.AddRange(new IEvaluator[] + public SpecificationEvaluator() { - WhereEvaluator.Instance, - SearchEvaluator.Instance, - IncludeEvaluator.Instance, - OrderEvaluator.Instance, - PaginationEvaluator.Instance, - AsNoTrackingEvaluator.Instance - }); - } - public SpecificationEvaluator(IEnumerable evaluators) - { - Evaluators.AddRange(evaluators); - } - - /// - public virtual IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class - { - if (specification is null) throw new ArgumentNullException("Specification is required"); - if (specification.Selector is null && specification.SelectorMany is null) throw new SelectorNotFoundException(); - if (specification.Selector != null && specification.SelectorMany != null) throw new ConcurrentSelectorsException(); - - query = GetQuery(query, (ISpecification)specification); - - return specification.Selector != null - ? query.Select(specification.Selector) - : query.SelectMany(specification.SelectorMany); - } - - /// - public virtual IQueryable GetQuery(IQueryable query, ISpecification specification, bool evaluateCriteriaOnly = false) where T : class - { - if (specification is null) throw new ArgumentNullException("Specification is required"); - - var evaluators = evaluateCriteriaOnly ? Evaluators.Where(x => x.IsCriteriaEvaluator) : Evaluators; - - foreach (var evaluator in evaluators) + Evaluators.AddRange(new IEvaluator[] + { + WhereEvaluator.Instance, + SearchEvaluator.Instance, + IncludeEvaluator.Instance, + OrderEvaluator.Instance, + PaginationEvaluator.Instance, + AsNoTrackingEvaluator.Instance + }); + } + public SpecificationEvaluator(IEnumerable evaluators) + { + Evaluators.AddRange(evaluators); + } + + /// + public virtual IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class { - query = evaluator.GetQuery(query, specification); + if (specification is null) throw new ArgumentNullException("Specification is required"); + if (specification.Selector is null && specification.SelectorMany is null) throw new SelectorNotFoundException(); + if (specification.Selector != null && specification.SelectorMany != null) throw new ConcurrentSelectorsException(); + + query = GetQuery(query, (ISpecification)specification); + + return specification.Selector != null + ? query.Select(specification.Selector) + : query.SelectMany(specification.SelectorMany); } - return query; - } + /// + public virtual IQueryable GetQuery(IQueryable query, ISpecification specification, bool evaluateCriteriaOnly = false) where T : class + { + if (specification is null) throw new ArgumentNullException("Specification is required"); + + var evaluators = evaluateCriteriaOnly ? Evaluators.Where(x => x.IsCriteriaEvaluator) : Evaluators; + + foreach (var evaluator in evaluators) + { + query = evaluator.GetQuery(query, specification); + } + + return query; + } } diff --git a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Extensions/DbSetExtensions.cs b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Extensions/DbSetExtensions.cs index 0494d693..75376321 100644 --- a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Extensions/DbSetExtensions.cs +++ b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Extensions/DbSetExtensions.cs @@ -8,49 +8,49 @@ namespace Ardalis.Specification.EntityFramework6; public static class DbSetExtensions { - public static async Task> ToListAsync( - this DbSet source, - ISpecification specification, - CancellationToken cancellationToken = default) - where TSource : class - { - var result = await SpecificationEvaluator.Default.GetQuery(source, specification).ToListAsync(cancellationToken); + public static async Task> ToListAsync( + this DbSet source, + ISpecification specification, + CancellationToken cancellationToken = default) + where TSource : class + { + var result = await SpecificationEvaluator.Default.GetQuery(source, specification).ToListAsync(cancellationToken); - return specification.PostProcessingAction == null - ? result - : specification.PostProcessingAction(result).ToList(); - } + return specification.PostProcessingAction == null + ? result + : specification.PostProcessingAction(result).ToList(); + } - public static async Task> ToEnumerableAsync( - this DbSet source, - ISpecification specification, - CancellationToken cancellationToken = default) - where TSource : class - { - var result = await SpecificationEvaluator.Default.GetQuery(source, specification).ToListAsync(cancellationToken); + public static async Task> ToEnumerableAsync( + this DbSet source, + ISpecification specification, + CancellationToken cancellationToken = default) + where TSource : class + { + var result = await SpecificationEvaluator.Default.GetQuery(source, specification).ToListAsync(cancellationToken); - return specification.PostProcessingAction == null - ? result - : specification.PostProcessingAction(result); - } + return specification.PostProcessingAction == null + ? result + : specification.PostProcessingAction(result); + } - public static IQueryable WithSpecification( - this IQueryable source, - ISpecification specification, - ISpecificationEvaluator evaluator = null) - where TSource : class - { - evaluator ??= SpecificationEvaluator.Default; - return evaluator.GetQuery(source, specification); - } + public static IQueryable WithSpecification( + this IQueryable source, + ISpecification specification, + ISpecificationEvaluator evaluator = null) + where TSource : class + { + evaluator ??= SpecificationEvaluator.Default; + return evaluator.GetQuery(source, specification); + } - public static IQueryable WithSpecification( - this IQueryable source, - ISpecification specification, - ISpecificationEvaluator evaluator = null) - where TSource : class - { - evaluator ??= SpecificationEvaluator.Default; - return evaluator.GetQuery(source, specification); - } + public static IQueryable WithSpecification( + this IQueryable source, + ISpecification specification, + ISpecificationEvaluator evaluator = null) + where TSource : class + { + evaluator ??= SpecificationEvaluator.Default; + return evaluator.GetQuery(source, specification); + } } diff --git a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Extensions/IncludeExtensions.cs b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Extensions/IncludeExtensions.cs index ff39c3a2..1a8dc420 100644 --- a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Extensions/IncludeExtensions.cs +++ b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Extensions/IncludeExtensions.cs @@ -9,56 +9,56 @@ namespace Ardalis.Specification.EntityFramework6; public static class IncludeExtensions { - public static IQueryable Include(this IQueryable source, IncludeExpressionInfo info) - { - _ = info ?? throw new ArgumentNullException(nameof(info)); - var propertyName = GetPropertyName(info.LambdaExpression); + public static IQueryable Include(this IQueryable source, IncludeExpressionInfo info) + { + _ = info ?? throw new ArgumentNullException(nameof(info)); + var propertyName = GetPropertyName(info.LambdaExpression); - return QueryableExtensions.Include(source, propertyName); - } + return QueryableExtensions.Include(source, propertyName); + } - public static IQueryable ThenInclude(this IQueryable source, IncludeExpressionInfo info) - { - _ = info ?? throw new ArgumentNullException(nameof(info)); - _ = info.PreviousPropertyType ?? throw new ArgumentNullException(nameof(info.PreviousPropertyType)); + public static IQueryable ThenInclude(this IQueryable source, IncludeExpressionInfo info) + { + _ = info ?? throw new ArgumentNullException(nameof(info)); + _ = info.PreviousPropertyType ?? throw new ArgumentNullException(nameof(info.PreviousPropertyType)); - var exp = source.Expression as MethodCallExpression; - var arg = exp.Arguments[0] as ConstantExpression; + var exp = source.Expression as MethodCallExpression; + var arg = exp.Arguments[0] as ConstantExpression; - string previousPropertyName; - if (arg.Value is string) - { - previousPropertyName = arg.Value.ToString(); - } - else - { - // System.Data.Entity.Core.Objects.Span is an internal class, so here's some reflection to get to the previous property. + string previousPropertyName; + if (arg.Value is string) + { + previousPropertyName = arg.Value.ToString(); + } + else + { + // System.Data.Entity.Core.Objects.Span is an internal class, so here's some reflection to get to the previous property. - var propertyInfo = arg.Value.GetType().GetProperty("SpanList", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); - var spanList = propertyInfo.GetValue(arg.Value); + var propertyInfo = arg.Value.GetType().GetProperty("SpanList", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + var spanList = propertyInfo.GetValue(arg.Value); - // Get the first item of the span list - propertyInfo = propertyInfo.PropertyType.GetProperty("Item"); - var spanPath = propertyInfo.GetValue(spanList, new object[] { 0 }); + // Get the first item of the span list + propertyInfo = propertyInfo.PropertyType.GetProperty("Item"); + var spanPath = propertyInfo.GetValue(spanList, new object[] { 0 }); - var fieldInfo = spanPath.GetType().GetField("Navigations", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); - var navigations = fieldInfo.GetValue(spanPath) as List; - previousPropertyName = string.Join(".", navigations); - } + var fieldInfo = spanPath.GetType().GetField("Navigations", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + var navigations = fieldInfo.GetValue(spanPath) as List; + previousPropertyName = string.Join(".", navigations); + } - var propertyName = GetPropertyName(info.LambdaExpression); + var propertyName = GetPropertyName(info.LambdaExpression); - return QueryableExtensions.Include(source, $"{previousPropertyName}.{propertyName}"); - } + return QueryableExtensions.Include(source, $"{previousPropertyName}.{propertyName}"); + } - private static string GetPropertyName(this Expression propertySelector, char delimiter = '.', char endTrim = ')') - { + private static string GetPropertyName(this Expression propertySelector, char delimiter = '.', char endTrim = ')') + { - var asString = propertySelector.ToString(); - var firstDelim = asString.IndexOf(delimiter); + var asString = propertySelector.ToString(); + var firstDelim = asString.IndexOf(delimiter); - return firstDelim < 0 - ? asString - : asString.Substring(firstDelim + 1).TrimEnd(endTrim); - } + return firstDelim < 0 + ? asString + : asString.Substring(firstDelim + 1).TrimEnd(endTrim); + } } diff --git a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Extensions/ParameterReplacerVisitor.cs b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Extensions/ParameterReplacerVisitor.cs index 15020078..d54d6a68 100644 --- a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Extensions/ParameterReplacerVisitor.cs +++ b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Extensions/ParameterReplacerVisitor.cs @@ -4,18 +4,18 @@ namespace Ardalis.Specification.EntityFramework6; internal class ParameterReplacerVisitor : ExpressionVisitor { - private readonly Expression _newExpression; - private readonly ParameterExpression _oldParameter; + private readonly Expression _newExpression; + private readonly ParameterExpression _oldParameter; - private ParameterReplacerVisitor(ParameterExpression oldParameter, Expression newExpression) - { - _oldParameter = oldParameter; - _newExpression = newExpression; - } + private ParameterReplacerVisitor(ParameterExpression oldParameter, Expression newExpression) + { + _oldParameter = oldParameter; + _newExpression = newExpression; + } - internal static Expression Replace(Expression expression, ParameterExpression oldParameter, Expression newExpression) - => new ParameterReplacerVisitor(oldParameter, newExpression).Visit(expression); + internal static Expression Replace(Expression expression, ParameterExpression oldParameter, Expression newExpression) + => new ParameterReplacerVisitor(oldParameter, newExpression).Visit(expression); - protected override Expression VisitParameter(ParameterExpression p) - => p == _oldParameter ? _newExpression : p; + protected override Expression VisitParameter(ParameterExpression p) + => p == _oldParameter ? _newExpression : p; } diff --git a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Extensions/SearchExtension.cs b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Extensions/SearchExtension.cs index 9061ed81..1a9df6bb 100644 --- a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Extensions/SearchExtension.cs +++ b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/Extensions/SearchExtension.cs @@ -8,46 +8,46 @@ namespace Ardalis.Specification.EntityFramework6; public static class SearchExtension { - /// - /// Filters by applying an 'SQL LIKE' operation to it. - /// - /// The type being queried against. - /// The sequence of - /// - /// - /// Selector, the property to apply the SQL LIKE against. - /// SearchTerm, the value to use for the SQL LIKE. - /// - /// - /// - public static IQueryable Search(this IQueryable source, IEnumerable> criterias) - { - Expression expr = null; - var parameter = Expression.Parameter(typeof(T), "x"); - - foreach (var criteria in criterias) + /// + /// Filters by applying an 'SQL LIKE' operation to it. + /// + /// The type being queried against. + /// The sequence of + /// + /// + /// Selector, the property to apply the SQL LIKE against. + /// SearchTerm, the value to use for the SQL LIKE. + /// + /// + /// + public static IQueryable Search(this IQueryable source, IEnumerable> criterias) { - var (selector, searchTerm) = (criteria.Selector, criteria.SearchTerm); - if (string.IsNullOrEmpty(criteria.SearchTerm)) - { - continue; - } + Expression expr = null; + var parameter = Expression.Parameter(typeof(T), "x"); - var like = typeof(DbFunctions).GetMethod(nameof(DbFunctions.Like), new Type[] { typeof(string), typeof(string) }); + foreach (var criteria in criterias) + { + var (selector, searchTerm) = (criteria.Selector, criteria.SearchTerm); + if (string.IsNullOrEmpty(criteria.SearchTerm)) + { + continue; + } - var propertySelector = ParameterReplacerVisitor.Replace(selector, selector.Parameters[0], parameter); + var like = typeof(DbFunctions).GetMethod(nameof(DbFunctions.Like), new Type[] { typeof(string), typeof(string) }); - var likeExpression = Expression.Call( - null, - like, - (propertySelector as LambdaExpression)?.Body, - Expression.Constant(searchTerm)); + var propertySelector = ParameterReplacerVisitor.Replace(selector, selector.Parameters[0], parameter); - expr = expr == null ? (Expression)likeExpression : Expression.OrElse(expr, likeExpression); - } + var likeExpression = Expression.Call( + null, + like, + (propertySelector as LambdaExpression)?.Body, + Expression.Constant(searchTerm)); + + expr = expr == null ? (Expression)likeExpression : Expression.OrElse(expr, likeExpression); + } - return expr == null - ? source - : source.Where(Expression.Lambda>(expr, parameter)); - } + return expr == null + ? source + : source.Where(Expression.Lambda>(expr, parameter)); + } } diff --git a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/RepositoryBaseOfT.cs b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/RepositoryBaseOfT.cs index 512280c1..eb4b5eb1 100644 --- a/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/RepositoryBaseOfT.cs +++ b/Specification.EntityFramework6/src/Ardalis.Specification.EntityFramework6/RepositoryBaseOfT.cs @@ -10,195 +10,195 @@ namespace Ardalis.Specification.EntityFramework6; /// public abstract class RepositoryBase : IRepositoryBase where T : class { - private readonly DbContext _dbContext; - private readonly ISpecificationEvaluator _specificationEvaluator; - - public RepositoryBase(DbContext dbContext) - : this(dbContext, SpecificationEvaluator.Default) - { - } - - /// - public RepositoryBase(DbContext dbContext, ISpecificationEvaluator specificationEvaluator) - { - _dbContext = dbContext; - _specificationEvaluator = specificationEvaluator; - } - - /// - public virtual async Task AddAsync(T entity, CancellationToken cancellationToken = default) - { - _dbContext.Set().Add(entity); - - await SaveChangesAsync(cancellationToken); - - return entity; - } - - /// - public virtual async Task> AddRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) - { - _dbContext.Set().AddRange(entities); - - await SaveChangesAsync(cancellationToken); - - return entities; - } - - /// - public virtual async Task UpdateAsync(T entity, CancellationToken cancellationToken = default) - { - _dbContext.Entry(entity).State = EntityState.Modified; - - await SaveChangesAsync(cancellationToken); - } - - /// - public virtual async Task UpdateRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) - { - foreach (var entity in entities) - { - _dbContext.Entry(entity).State = EntityState.Modified; - } - - await SaveChangesAsync(cancellationToken); - } - - /// - public virtual async Task DeleteAsync(T entity, CancellationToken cancellationToken = default) - { - _dbContext.Set().Remove(entity); - - await SaveChangesAsync(cancellationToken); - } - - /// - public virtual async Task DeleteRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) - { - _dbContext.Set().RemoveRange(entities); - - await SaveChangesAsync(cancellationToken); - } - - /// - public virtual async Task SaveChangesAsync(CancellationToken cancellationToken = default) - { - return await _dbContext.SaveChangesAsync(cancellationToken); - } - - /// - public virtual async Task GetByIdAsync(TId id, CancellationToken cancellationToken = default) - { - return await _dbContext.Set().FindAsync(cancellationToken: cancellationToken, new object[] { id }); - } - - /// - [Obsolete] - public virtual async Task GetBySpecAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - return await ApplySpecification(specification).FirstOrDefaultAsync(cancellationToken); - } - - /// - [Obsolete] - public virtual async Task GetBySpecAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - return await ApplySpecification(specification).FirstOrDefaultAsync(cancellationToken); - } - - /// - public virtual async Task FirstOrDefaultAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - return await ApplySpecification(specification).FirstOrDefaultAsync(cancellationToken); - } - - /// - public virtual async Task FirstOrDefaultAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - return await ApplySpecification(specification).FirstOrDefaultAsync(cancellationToken); - } - - /// - public virtual async Task SingleOrDefaultAsync(ISingleResultSpecification specification, CancellationToken cancellationToken = default) - { - return await ApplySpecification(specification).SingleOrDefaultAsync(cancellationToken); - } - - /// - public virtual async Task SingleOrDefaultAsync(ISingleResultSpecification specification, CancellationToken cancellationToken = default) - { - return await ApplySpecification(specification).SingleOrDefaultAsync(cancellationToken); - } - - /// - public virtual async Task> ListAsync(CancellationToken cancellationToken = default) - { - return await _dbContext.Set().ToListAsync(cancellationToken); - } - - /// - public virtual async Task> ListAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - var queryResult = await ApplySpecification(specification).ToListAsync(cancellationToken); - - return specification.PostProcessingAction == null ? queryResult : specification.PostProcessingAction(queryResult).ToList(); - } - - /// - public virtual async Task> ListAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - var queryResult = await ApplySpecification(specification).ToListAsync(cancellationToken); - - return specification.PostProcessingAction == null ? queryResult : specification.PostProcessingAction(queryResult).ToList(); - } - - /// - public virtual async Task CountAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - return await ApplySpecification(specification, true).CountAsync(cancellationToken); - } - - /// - public virtual async Task CountAsync(CancellationToken cancellationToken = default) - { - return await _dbContext.Set().CountAsync(cancellationToken); - } - - /// - public virtual async Task AnyAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - return await ApplySpecification(specification, true).AnyAsync(cancellationToken); - } - - /// - public virtual async Task AnyAsync(CancellationToken cancellationToken = default) - { - return await _dbContext.Set().AnyAsync(cancellationToken); - } - - /// - /// Filters the entities of , to those that match the encapsulated query logic of the - /// . - /// - /// The encapsulated query logic. - /// The filtered entities as an . - protected virtual IQueryable ApplySpecification(ISpecification specification, bool evaluateCriteriaOnly = false) - { - return _specificationEvaluator.GetQuery(_dbContext.Set().AsQueryable(), specification, evaluateCriteriaOnly); - } - - /// - /// Filters all entities of , that matches the encapsulated query logic of the - /// , from the database. - /// - /// Projects each entity into a new form, being . - /// - /// - /// The type of the value returned by the projection. - /// The encapsulated query logic. - /// The filtered projected entities as an . - protected virtual IQueryable ApplySpecification(ISpecification specification) - { - return _specificationEvaluator.GetQuery(_dbContext.Set().AsQueryable(), specification); - } + private readonly DbContext _dbContext; + private readonly ISpecificationEvaluator _specificationEvaluator; + + public RepositoryBase(DbContext dbContext) + : this(dbContext, SpecificationEvaluator.Default) + { + } + + /// + public RepositoryBase(DbContext dbContext, ISpecificationEvaluator specificationEvaluator) + { + _dbContext = dbContext; + _specificationEvaluator = specificationEvaluator; + } + + /// + public virtual async Task AddAsync(T entity, CancellationToken cancellationToken = default) + { + _dbContext.Set().Add(entity); + + await SaveChangesAsync(cancellationToken); + + return entity; + } + + /// + public virtual async Task> AddRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) + { + _dbContext.Set().AddRange(entities); + + await SaveChangesAsync(cancellationToken); + + return entities; + } + + /// + public virtual async Task UpdateAsync(T entity, CancellationToken cancellationToken = default) + { + _dbContext.Entry(entity).State = EntityState.Modified; + + await SaveChangesAsync(cancellationToken); + } + + /// + public virtual async Task UpdateRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) + { + foreach (var entity in entities) + { + _dbContext.Entry(entity).State = EntityState.Modified; + } + + await SaveChangesAsync(cancellationToken); + } + + /// + public virtual async Task DeleteAsync(T entity, CancellationToken cancellationToken = default) + { + _dbContext.Set().Remove(entity); + + await SaveChangesAsync(cancellationToken); + } + + /// + public virtual async Task DeleteRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) + { + _dbContext.Set().RemoveRange(entities); + + await SaveChangesAsync(cancellationToken); + } + + /// + public virtual async Task SaveChangesAsync(CancellationToken cancellationToken = default) + { + return await _dbContext.SaveChangesAsync(cancellationToken); + } + + /// + public virtual async Task GetByIdAsync(TId id, CancellationToken cancellationToken = default) + { + return await _dbContext.Set().FindAsync(cancellationToken: cancellationToken, new object[] { id }); + } + + /// + [Obsolete] + public virtual async Task GetBySpecAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + return await ApplySpecification(specification).FirstOrDefaultAsync(cancellationToken); + } + + /// + [Obsolete] + public virtual async Task GetBySpecAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + return await ApplySpecification(specification).FirstOrDefaultAsync(cancellationToken); + } + + /// + public virtual async Task FirstOrDefaultAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + return await ApplySpecification(specification).FirstOrDefaultAsync(cancellationToken); + } + + /// + public virtual async Task FirstOrDefaultAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + return await ApplySpecification(specification).FirstOrDefaultAsync(cancellationToken); + } + + /// + public virtual async Task SingleOrDefaultAsync(ISingleResultSpecification specification, CancellationToken cancellationToken = default) + { + return await ApplySpecification(specification).SingleOrDefaultAsync(cancellationToken); + } + + /// + public virtual async Task SingleOrDefaultAsync(ISingleResultSpecification specification, CancellationToken cancellationToken = default) + { + return await ApplySpecification(specification).SingleOrDefaultAsync(cancellationToken); + } + + /// + public virtual async Task> ListAsync(CancellationToken cancellationToken = default) + { + return await _dbContext.Set().ToListAsync(cancellationToken); + } + + /// + public virtual async Task> ListAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + var queryResult = await ApplySpecification(specification).ToListAsync(cancellationToken); + + return specification.PostProcessingAction == null ? queryResult : specification.PostProcessingAction(queryResult).ToList(); + } + + /// + public virtual async Task> ListAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + var queryResult = await ApplySpecification(specification).ToListAsync(cancellationToken); + + return specification.PostProcessingAction == null ? queryResult : specification.PostProcessingAction(queryResult).ToList(); + } + + /// + public virtual async Task CountAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + return await ApplySpecification(specification, true).CountAsync(cancellationToken); + } + + /// + public virtual async Task CountAsync(CancellationToken cancellationToken = default) + { + return await _dbContext.Set().CountAsync(cancellationToken); + } + + /// + public virtual async Task AnyAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + return await ApplySpecification(specification, true).AnyAsync(cancellationToken); + } + + /// + public virtual async Task AnyAsync(CancellationToken cancellationToken = default) + { + return await _dbContext.Set().AnyAsync(cancellationToken); + } + + /// + /// Filters the entities of , to those that match the encapsulated query logic of the + /// . + /// + /// The encapsulated query logic. + /// The filtered entities as an . + protected virtual IQueryable ApplySpecification(ISpecification specification, bool evaluateCriteriaOnly = false) + { + return _specificationEvaluator.GetQuery(_dbContext.Set().AsQueryable(), specification, evaluateCriteriaOnly); + } + + /// + /// Filters all entities of , that matches the encapsulated query logic of the + /// , from the database. + /// + /// Projects each entity into a new form, being . + /// + /// + /// The type of the value returned by the projection. + /// The encapsulated query logic. + /// The filtered projected entities as an . + protected virtual IQueryable ApplySpecification(ISpecification specification) + { + return _specificationEvaluator.GetQuery(_dbContext.Set().AsQueryable(), specification); + } } diff --git a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/Configurations/AddressConfiguration.cs b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/Configurations/AddressConfiguration.cs index ce2557aa..beaef87d 100644 --- a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/Configurations/AddressConfiguration.cs +++ b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/Configurations/AddressConfiguration.cs @@ -5,9 +5,9 @@ namespace Ardalis.Specification.EntityFramework6.IntegrationTests.Fixture.Config public class AddressConfiguration : EntityTypeConfiguration
{ - public AddressConfiguration() - { - ToTable("Address"); - HasKey(c => c.Id); - } + public AddressConfiguration() + { + ToTable("Address"); + HasKey(c => c.Id); + } } diff --git a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/Configurations/CompanyConfiguration.cs b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/Configurations/CompanyConfiguration.cs index 21ca1302..3d641085 100644 --- a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/Configurations/CompanyConfiguration.cs +++ b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/Configurations/CompanyConfiguration.cs @@ -5,15 +5,15 @@ namespace Ardalis.Specification.EntityFramework6.IntegrationTests.Fixture.Config public class CompanyConfiguration : EntityTypeConfiguration { - public CompanyConfiguration() - { - ToTable("Company"); - HasKey(c => c.Id); + public CompanyConfiguration() + { + ToTable("Company"); + HasKey(c => c.Id); - Property(c => c.Id) - .HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.None); + Property(c => c.Id) + .HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.None); - //HasMany(c => c.Stores) - // .WithRequired(s => s.Company); - } + //HasMany(c => c.Stores) + // .WithRequired(s => s.Company); + } } diff --git a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/Configurations/CountryConfiguration.cs b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/Configurations/CountryConfiguration.cs index 653ac7c0..3dada338 100644 --- a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/Configurations/CountryConfiguration.cs +++ b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/Configurations/CountryConfiguration.cs @@ -5,9 +5,9 @@ namespace Ardalis.Specification.EntityFramework6.IntegrationTests.Fixture.Config public class CountryConfiguration : EntityTypeConfiguration { - public CountryConfiguration() - { - ToTable("Country"); - HasKey(c => c.Id); - } + public CountryConfiguration() + { + ToTable("Country"); + HasKey(c => c.Id); + } } diff --git a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/Configurations/ProductConfiguration.cs b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/Configurations/ProductConfiguration.cs index 7e739662..77179ea4 100644 --- a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/Configurations/ProductConfiguration.cs +++ b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/Configurations/ProductConfiguration.cs @@ -5,9 +5,9 @@ namespace Ardalis.Specification.EntityFramework6.IntegrationTests.Fixture.Config public class ProductConfiguration : EntityTypeConfiguration { - public ProductConfiguration() - { - ToTable("Product"); - HasKey(c => c.Id); - } + public ProductConfiguration() + { + ToTable("Product"); + HasKey(c => c.Id); + } } diff --git a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/Configurations/StoreConfiguration.cs b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/Configurations/StoreConfiguration.cs index 1ee87362..e86d309d 100644 --- a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/Configurations/StoreConfiguration.cs +++ b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/Configurations/StoreConfiguration.cs @@ -5,12 +5,12 @@ namespace Ardalis.Specification.EntityFramework6.IntegrationTests.Fixture.Config public class StoreConfiguration : EntityTypeConfiguration { - public StoreConfiguration() - { - ToTable("Store"); - HasKey(c => c.Id); + public StoreConfiguration() + { + ToTable("Store"); + HasKey(c => c.Id); - HasOptional(s => s.Address) - .WithRequired(x => x.Store); - } + HasOptional(s => s.Address) + .WithRequired(x => x.Store); + } } diff --git a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/DbInitializer.cs b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/DbInitializer.cs index 736aaa64..117ae0ae 100644 --- a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/DbInitializer.cs +++ b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/DbInitializer.cs @@ -5,16 +5,16 @@ namespace Ardalis.Specification.EntityFramework6.IntegrationTests.Fixture; public class DbInitializer : CreateDatabaseIfNotExists { - protected override void Seed(TestDbContext context) - { - base.Seed(context); + protected override void Seed(TestDbContext context) + { + base.Seed(context); - context.Addresses.AddRange(AddressSeed.Get()); - context.Countries.AddRange(CountrySeed.Get()); - context.Companies.AddRange(CompanySeed.Get()); - context.Products.AddRange(ProductSeed.Get()); - context.Stores.AddRange(StoreSeed.Get()); + context.Addresses.AddRange(AddressSeed.Get()); + context.Countries.AddRange(CountrySeed.Get()); + context.Companies.AddRange(CompanySeed.Get()); + context.Products.AddRange(ProductSeed.Get()); + context.Stores.AddRange(StoreSeed.Get()); - context.SaveChanges(); - } + context.SaveChanges(); + } } diff --git a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/IntegrationTestBase.cs b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/IntegrationTestBase.cs index c35259da..97083010 100644 --- a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/IntegrationTestBase.cs +++ b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/IntegrationTestBase.cs @@ -5,15 +5,15 @@ namespace Ardalis.Specification.EntityFramework6.IntegrationTests.Fixture; public class IntegrationTestBase : IClassFixture { - protected TestDbContext dbContext; - protected Repository companyRepository; - protected Repository storeRepository; + protected TestDbContext dbContext; + protected Repository companyRepository; + protected Repository storeRepository; - public IntegrationTestBase(SharedDatabaseFixture fixture) - { - dbContext = fixture.CreateContext(); + public IntegrationTestBase(SharedDatabaseFixture fixture) + { + dbContext = fixture.CreateContext(); - companyRepository = new Repository(dbContext); - storeRepository = new Repository(dbContext); - } + companyRepository = new Repository(dbContext); + storeRepository = new Repository(dbContext); + } } diff --git a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/RepositoryOfT.cs b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/RepositoryOfT.cs index 9809bd5b..c2b3516a 100644 --- a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/RepositoryOfT.cs +++ b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/RepositoryOfT.cs @@ -3,10 +3,10 @@ /// public class Repository : RepositoryBase where T : class { - protected readonly TestDbContext dbContext; + protected readonly TestDbContext dbContext; - public Repository(TestDbContext dbContext) : base(dbContext) - { - this.dbContext = dbContext; - } + public Repository(TestDbContext dbContext) : base(dbContext) + { + this.dbContext = dbContext; + } } diff --git a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/SharedDatabaseFixture.cs b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/SharedDatabaseFixture.cs index b21710da..840472e8 100644 --- a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/SharedDatabaseFixture.cs +++ b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/SharedDatabaseFixture.cs @@ -7,40 +7,40 @@ namespace Ardalis.Specification.EntityFramework6.IntegrationTests.Fixture; public class SharedDatabaseFixture : IDisposable { - // (docker) - public const string _connectionStringDocker = "Data Source=databaseEF6;Initial Catalog=SpecificationEF6TestsDB;PersistSecurityInfo=True;User ID=sa;Password=P@ssW0rd!"; + // (docker) + public const string _connectionStringDocker = "Data Source=databaseEF6;Initial Catalog=SpecificationEF6TestsDB;PersistSecurityInfo=True;User ID=sa;Password=P@ssW0rd!"; - // (localdb) - public const string _connectionStringLocalDb = "Server=(localdb)\\mssqllocaldb;Integrated Security=SSPI;Initial Catalog=SpecificationEF6TestsDB;ConnectRetryCount=0"; + // (localdb) + public const string _connectionStringLocalDb = "Server=(localdb)\\mssqllocaldb;Integrated Security=SSPI;Initial Catalog=SpecificationEF6TestsDB;ConnectRetryCount=0"; - public SharedDatabaseFixture() - { - var isLocalDBInstalled = false; - - using (var localDB = new SqlLocalDbApi()) + public SharedDatabaseFixture() { - isLocalDBInstalled = localDB.IsLocalDBInstalled(); - } + var isLocalDBInstalled = false; - Connection = isLocalDBInstalled - ? new SqlConnection(_connectionStringLocalDb) - : new SqlConnection(_connectionStringDocker); - } + using (var localDB = new SqlLocalDbApi()) + { + isLocalDBInstalled = localDB.IsLocalDBInstalled(); + } - public DbConnection Connection { get; } + Connection = isLocalDBInstalled + ? new SqlConnection(_connectionStringLocalDb) + : new SqlConnection(_connectionStringDocker); + } - public TestDbContext CreateContext(DbTransaction transaction = null) - { - var context = new TestDbContext(Connection); + public DbConnection Connection { get; } - if (transaction != null) + public TestDbContext CreateContext(DbTransaction transaction = null) { - context.Database.UseTransaction(transaction); - } + var context = new TestDbContext(Connection); + + if (transaction != null) + { + context.Database.UseTransaction(transaction); + } - return context; - } + return context; + } - public void Dispose() => Connection.Dispose(); + public void Dispose() => Connection.Dispose(); } diff --git a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/TestDbContext.cs b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/TestDbContext.cs index 4afa5d81..fc1524d1 100644 --- a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/TestDbContext.cs +++ b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/Fixture/TestDbContext.cs @@ -10,29 +10,29 @@ namespace Ardalis.Specification.EntityFramework6.IntegrationTests.Fixture; public class TestDbContext : DbContext { - public TestDbContext(DbConnection connection) : base(connection, false) - { - Database.SetInitializer(new DbInitializer()); - } + public TestDbContext(DbConnection connection) : base(connection, false) + { + Database.SetInitializer(new DbInitializer()); + } - public virtual DbSet Countries { get; set; } - public virtual DbSet Companies { get; set; } - public virtual DbSet Stores { get; set; } - public virtual DbSet
Addresses { get; set; } - public virtual DbSet Products { get; set; } + public virtual DbSet Countries { get; set; } + public virtual DbSet Companies { get; set; } + public virtual DbSet Stores { get; set; } + public virtual DbSet
Addresses { get; set; } + public virtual DbSet Products { get; set; } - protected override void OnModelCreating(DbModelBuilder modelBuilder) - { - var typesToRegister = Assembly.GetExecutingAssembly().GetTypes() - .Where(type => !string.IsNullOrEmpty(type.Namespace)) - .Where(type => type.BaseType != null && type.BaseType.IsGenericType - && type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>)); - foreach (var type in typesToRegister) + protected override void OnModelCreating(DbModelBuilder modelBuilder) { - dynamic configurationInstance = Activator.CreateInstance(type); - modelBuilder.Configurations.Add(configurationInstance); - } + var typesToRegister = Assembly.GetExecutingAssembly().GetTypes() + .Where(type => !string.IsNullOrEmpty(type.Namespace)) + .Where(type => type.BaseType != null && type.BaseType.IsGenericType + && type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>)); + foreach (var type in typesToRegister) + { + dynamic configurationInstance = Activator.CreateInstance(type); + modelBuilder.Configurations.Add(configurationInstance); + } - base.OnModelCreating(modelBuilder); - } + base.OnModelCreating(modelBuilder); + } } diff --git a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/RepositoryOfT_AnyAsync.cs b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/RepositoryOfT_AnyAsync.cs index 30c1983c..349b2465 100644 --- a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/RepositoryOfT_AnyAsync.cs +++ b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/RepositoryOfT_AnyAsync.cs @@ -9,29 +9,29 @@ namespace Ardalis.Specification.EntityFramework6.IntegrationTests; public class RepositoryOfT_AnyAsync : IntegrationTestBase { - public RepositoryOfT_AnyAsync(SharedDatabaseFixture fixture) : base(fixture) { } + public RepositoryOfT_AnyAsync(SharedDatabaseFixture fixture) : base(fixture) { } - [Fact] - public async Task ReturnsTrueOnStoresRecords_WithoutSpec() - { - var result = await storeRepository.AnyAsync(); + [Fact] + public async Task ReturnsTrueOnStoresRecords_WithoutSpec() + { + var result = await storeRepository.AnyAsync(); - result.Should().BeTrue(); - } + result.Should().BeTrue(); + } - [Fact] - public async Task ReturnsTrue_GivenStoreByIdSpecWithValidStore() - { - var result = await storeRepository.AnyAsync(new StoreByIdSpec(StoreSeed.VALID_STORE_ID)); + [Fact] + public async Task ReturnsTrue_GivenStoreByIdSpecWithValidStore() + { + var result = await storeRepository.AnyAsync(new StoreByIdSpec(StoreSeed.VALID_STORE_ID)); - result.Should().BeTrue(); - } + result.Should().BeTrue(); + } - [Fact] - public async Task ReturnsFalse_GivenStoreByIdSpecWithInvalidStore() - { - var result = await storeRepository.AnyAsync(new StoreByIdSpec(0)); + [Fact] + public async Task ReturnsFalse_GivenStoreByIdSpecWithInvalidStore() + { + var result = await storeRepository.AnyAsync(new StoreByIdSpec(0)); - result.Should().BeFalse(); - } + result.Should().BeFalse(); + } } diff --git a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/RepositoryOfT_GetById.cs b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/RepositoryOfT_GetById.cs index 7aab7214..a53c03df 100644 --- a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/RepositoryOfT_GetById.cs +++ b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/RepositoryOfT_GetById.cs @@ -8,23 +8,23 @@ namespace Ardalis.Specification.EntityFramework6.IntegrationTests; public class RepositoryOfT_GetById : IntegrationTestBase { - public RepositoryOfT_GetById(SharedDatabaseFixture fixture) : base(fixture) { } + public RepositoryOfT_GetById(SharedDatabaseFixture fixture) : base(fixture) { } - [Fact] - public async Task ReturnsStore_GivenId() - { - var result = await storeRepository.GetByIdAsync(StoreSeed.VALID_STORE_ID); + [Fact] + public async Task ReturnsStore_GivenId() + { + var result = await storeRepository.GetByIdAsync(StoreSeed.VALID_STORE_ID); - result.Should().NotBeNull(); - result.Name.Should().Be(StoreSeed.VALID_STORE_NAME); - } + result.Should().NotBeNull(); + result.Name.Should().Be(StoreSeed.VALID_STORE_NAME); + } - [Fact] - public async Task ReturnsStore_GivenGenericId() - { - var result = await storeRepository.GetByIdAsync(StoreSeed.VALID_STORE_ID); + [Fact] + public async Task ReturnsStore_GivenGenericId() + { + var result = await storeRepository.GetByIdAsync(StoreSeed.VALID_STORE_ID); - result.Should().NotBeNull(); - result.Name.Should().Be(StoreSeed.VALID_STORE_NAME); - } + result.Should().NotBeNull(); + result.Name.Should().Be(StoreSeed.VALID_STORE_NAME); + } } diff --git a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/RepositoryOfT_GetBySpec.cs b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/RepositoryOfT_GetBySpec.cs index 14438e2e..41480ff1 100644 --- a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/RepositoryOfT_GetBySpec.cs +++ b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/RepositoryOfT_GetBySpec.cs @@ -11,93 +11,93 @@ namespace Ardalis.Specification.EntityFramework6.IntegrationTests; public class RepositoryOfT_GetBySpec : IntegrationTestBase { - public RepositoryOfT_GetBySpec(SharedDatabaseFixture fixture) : base(fixture) { } - - [Fact] - public async Task ReturnsStoreWithProducts_GivenStoreByIdIncludeProductsSpec() - { - var result = await storeRepository.GetBySpecAsync(new StoreByIdIncludeProductsSpec(StoreSeed.VALID_STORE_ID)); - - result.Should().NotBeNull(); - result.Name.Should().Be(StoreSeed.VALID_STORE_NAME); - result.Products.Count.Should().BeGreaterThan(1); - } - - [Fact] - public async Task ReturnsStoreWithAddress_GivenStoreByIdIncludeAddressSpec() - { - var result = await storeRepository.GetBySpecAsync(new StoreByIdIncludeAddressSpec(StoreSeed.VALID_STORE_ID)); - - result.Should().NotBeNull(); - result.Name.Should().Be(StoreSeed.VALID_STORE_NAME); - result.Address?.Street.Should().Be(AddressSeed.VALID_STREET_FOR_STOREID1); - } - - [Fact] - public async Task ReturnsStoreWithAddressAndProduct_GivenStoreByIdIncludeAddressAndProductsSpec() - { - var result = await storeRepository.GetBySpecAsync(new StoreByIdIncludeAddressAndProductsSpec(StoreSeed.VALID_STORE_ID)); - - result.Should().NotBeNull(); - result.Name.Should().Be(StoreSeed.VALID_STORE_NAME); - result.Products.Count.Should().BeGreaterThan(1); - result.Address?.Street.Should().Be(AddressSeed.VALID_STREET_FOR_STOREID1); - } - - [Fact] - public async Task ReturnsStoreWithProducts_GivenStoreByIdIncludeProductsUsingStringSpec() - { - var result = await storeRepository.GetBySpecAsync(new StoreByIdIncludeProductsUsingStringSpec(StoreSeed.VALID_STORE_ID)); - - result.Should().NotBeNull(); - result.Name.Should().Be(StoreSeed.VALID_STORE_NAME); - result.Products.Count.Should().BeGreaterThan(1); - } - - [Fact] - public async Task ReturnsCompanyWithStoresAndAddress_GivenCompanyByIdIncludeStoresThenIncludeAddressSpec() - { - var result = await companyRepository.GetBySpecAsync(new CompanyByIdIncludeStoresThenIncludeAddressSpec(CompanySeed.VALID_COMPANY_ID)); - - result.Should().NotBeNull(); - result.Name.Should().Be(CompanySeed.VALID_COMPANY_NAME); - result.Stores.Count.Should().BeGreaterThan(49); - result.Stores.Select(x => x.Address).Count().Should().BeGreaterThan(0); - } - - [Fact] - public async Task ReturnsCompanyWithStoresAndProducts_GivenCompanyByIdIncludeStoresThenIncludeProductsSpec() - { - var result = await companyRepository.GetBySpecAsync(new CompanyByIdIncludeStoresThenIncludeProductsSpec(CompanySeed.VALID_COMPANY_ID)); - - result.Should().NotBeNull(); - result.Name.Should().Be(CompanySeed.VALID_COMPANY_NAME); - result.Stores.Count.Should().BeGreaterThan(49); - result.Stores.Select(x => x.Products).Count().Should().BeGreaterThan(1); - } - - [Fact] - public async Task ReturnsUntrackedCompany_GivenCompanyByIdAsUntrackedSpec() - { - //dbContext.ChangeTracker.Clear(); - - var result = await companyRepository.GetBySpecAsync(new CompanyByIdAsUntrackedSpec(CompanySeed.VALID_COMPANY_ID)); - - result.Should().NotBeNull(); - result?.Name.Should().Be(CompanySeed.VALID_COMPANY_NAME); - dbContext.Entry(result).State.Should().Be(EntityState.Detached); - } - - [Fact] - public async Task ReturnsStoreWithCompanyAndCountryAndStoresForCompany_GivenStoreByIdIncludeCompanyAndCountryAndStoresForCompanySpec() - { - var result = await storeRepository.GetBySpecAsync(new StoreByIdIncludeCompanyAndCountryAndStoresForCompanySpec(StoreSeed.VALID_STORE_ID)); - - result.Should().NotBeNull(); - result.Name.Should().Be(StoreSeed.VALID_STORE_NAME); - result.Company.Should().NotBeNull(); - result.Company?.Country.Should().NotBeNull(); - result.Company?.Stores.Should().HaveCountGreaterOrEqualTo(2); - result.Company?.Stores?.Should().Match(x => x.Any(z => z.Products.Count > 0)); - } + public RepositoryOfT_GetBySpec(SharedDatabaseFixture fixture) : base(fixture) { } + + [Fact] + public async Task ReturnsStoreWithProducts_GivenStoreByIdIncludeProductsSpec() + { + var result = await storeRepository.GetBySpecAsync(new StoreByIdIncludeProductsSpec(StoreSeed.VALID_STORE_ID)); + + result.Should().NotBeNull(); + result.Name.Should().Be(StoreSeed.VALID_STORE_NAME); + result.Products.Count.Should().BeGreaterThan(1); + } + + [Fact] + public async Task ReturnsStoreWithAddress_GivenStoreByIdIncludeAddressSpec() + { + var result = await storeRepository.GetBySpecAsync(new StoreByIdIncludeAddressSpec(StoreSeed.VALID_STORE_ID)); + + result.Should().NotBeNull(); + result.Name.Should().Be(StoreSeed.VALID_STORE_NAME); + result.Address?.Street.Should().Be(AddressSeed.VALID_STREET_FOR_STOREID1); + } + + [Fact] + public async Task ReturnsStoreWithAddressAndProduct_GivenStoreByIdIncludeAddressAndProductsSpec() + { + var result = await storeRepository.GetBySpecAsync(new StoreByIdIncludeAddressAndProductsSpec(StoreSeed.VALID_STORE_ID)); + + result.Should().NotBeNull(); + result.Name.Should().Be(StoreSeed.VALID_STORE_NAME); + result.Products.Count.Should().BeGreaterThan(1); + result.Address?.Street.Should().Be(AddressSeed.VALID_STREET_FOR_STOREID1); + } + + [Fact] + public async Task ReturnsStoreWithProducts_GivenStoreByIdIncludeProductsUsingStringSpec() + { + var result = await storeRepository.GetBySpecAsync(new StoreByIdIncludeProductsUsingStringSpec(StoreSeed.VALID_STORE_ID)); + + result.Should().NotBeNull(); + result.Name.Should().Be(StoreSeed.VALID_STORE_NAME); + result.Products.Count.Should().BeGreaterThan(1); + } + + [Fact] + public async Task ReturnsCompanyWithStoresAndAddress_GivenCompanyByIdIncludeStoresThenIncludeAddressSpec() + { + var result = await companyRepository.GetBySpecAsync(new CompanyByIdIncludeStoresThenIncludeAddressSpec(CompanySeed.VALID_COMPANY_ID)); + + result.Should().NotBeNull(); + result.Name.Should().Be(CompanySeed.VALID_COMPANY_NAME); + result.Stores.Count.Should().BeGreaterThan(49); + result.Stores.Select(x => x.Address).Count().Should().BeGreaterThan(0); + } + + [Fact] + public async Task ReturnsCompanyWithStoresAndProducts_GivenCompanyByIdIncludeStoresThenIncludeProductsSpec() + { + var result = await companyRepository.GetBySpecAsync(new CompanyByIdIncludeStoresThenIncludeProductsSpec(CompanySeed.VALID_COMPANY_ID)); + + result.Should().NotBeNull(); + result.Name.Should().Be(CompanySeed.VALID_COMPANY_NAME); + result.Stores.Count.Should().BeGreaterThan(49); + result.Stores.Select(x => x.Products).Count().Should().BeGreaterThan(1); + } + + [Fact] + public async Task ReturnsUntrackedCompany_GivenCompanyByIdAsUntrackedSpec() + { + //dbContext.ChangeTracker.Clear(); + + var result = await companyRepository.GetBySpecAsync(new CompanyByIdAsUntrackedSpec(CompanySeed.VALID_COMPANY_ID)); + + result.Should().NotBeNull(); + result?.Name.Should().Be(CompanySeed.VALID_COMPANY_NAME); + dbContext.Entry(result).State.Should().Be(EntityState.Detached); + } + + [Fact] + public async Task ReturnsStoreWithCompanyAndCountryAndStoresForCompany_GivenStoreByIdIncludeCompanyAndCountryAndStoresForCompanySpec() + { + var result = await storeRepository.GetBySpecAsync(new StoreByIdIncludeCompanyAndCountryAndStoresForCompanySpec(StoreSeed.VALID_STORE_ID)); + + result.Should().NotBeNull(); + result.Name.Should().Be(StoreSeed.VALID_STORE_NAME); + result.Company.Should().NotBeNull(); + result.Company?.Country.Should().NotBeNull(); + result.Company?.Stores.Should().HaveCountGreaterOrEqualTo(2); + result.Company?.Stores?.Should().Match(x => x.Any(z => z.Products.Count > 0)); + } } diff --git a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/RepositoryOfT_ListAsync.cs b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/RepositoryOfT_ListAsync.cs index 0f3a57c3..0c40567d 100644 --- a/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/RepositoryOfT_ListAsync.cs +++ b/Specification.EntityFramework6/tests/Ardalis.Specification.EntityFramework6.IntegrationTests/RepositoryOfT_ListAsync.cs @@ -10,174 +10,174 @@ namespace Ardalis.Specification.EntityFramework6.IntegrationTests; public class RepositoryOfT_ListAsync : IntegrationTestBase { - public RepositoryOfT_ListAsync(SharedDatabaseFixture fixture) : base(fixture) { } - - [Fact] - public async Task ReturnsStoreWithProducts_GivenStoreIncludeProductsSpec() - { - var result = await storeRepository.ListAsync(new StoreIncludeProductsSpec()); + public RepositoryOfT_ListAsync(SharedDatabaseFixture fixture) : base(fixture) { } + + [Fact] + public async Task ReturnsStoreWithProducts_GivenStoreIncludeProductsSpec() + { + var result = await storeRepository.ListAsync(new StoreIncludeProductsSpec()); - result.Should().NotBeNull(); - result.Should().NotBeEmpty(); - result[0].Products.Should().NotBeEmpty(); - } - - [Fact] - public async Task ReturnsStoreWithAddress_GivenStoreIncludeAddressSpec() - { - var result = await storeRepository.ListAsync(new StoreIncludeAddressSpec()); - - result.Should().NotBeNull(); - result.Should().NotBeEmpty(); - result[0].Address.Should().NotBeNull(); - } + result.Should().NotBeNull(); + result.Should().NotBeEmpty(); + result[0].Products.Should().NotBeEmpty(); + } + + [Fact] + public async Task ReturnsStoreWithAddress_GivenStoreIncludeAddressSpec() + { + var result = await storeRepository.ListAsync(new StoreIncludeAddressSpec()); + + result.Should().NotBeNull(); + result.Should().NotBeEmpty(); + result[0].Address.Should().NotBeNull(); + } - [Fact] - public async Task ReturnsStoreWithAddressAndProduct_GivenStoreIncludeAddressAndProductsSpec() - { - var result = await storeRepository.ListAsync(new StoreIncludeAddressAndProductsSpec()); + [Fact] + public async Task ReturnsStoreWithAddressAndProduct_GivenStoreIncludeAddressAndProductsSpec() + { + var result = await storeRepository.ListAsync(new StoreIncludeAddressAndProductsSpec()); - result.Should().NotBeNull(); - result.Should().NotBeEmpty(); - result[0].Address.Should().NotBeNull(); - result[0].Products.Should().NotBeEmpty(); - } + result.Should().NotBeNull(); + result.Should().NotBeEmpty(); + result[0].Address.Should().NotBeNull(); + result[0].Products.Should().NotBeEmpty(); + } - [Fact] - public async Task ReturnsStoreWithIdFrom15To30_GivenStoresByIdListSpec() - { - var ids = Enumerable.Range(15, 16); - var spec = new StoresByIdListSpec(ids); + [Fact] + public async Task ReturnsStoreWithIdFrom15To30_GivenStoresByIdListSpec() + { + var ids = Enumerable.Range(15, 16); + var spec = new StoresByIdListSpec(ids); - var stores = await storeRepository.ListAsync(spec); + var stores = await storeRepository.ListAsync(spec); - stores.Count.Should().Be(16); - stores.OrderBy(x => x.Id).First().Id.Should().Be(15); - stores.OrderBy(x => x.Id).Last().Id.Should().Be(30); - } + stores.Count.Should().Be(16); + stores.OrderBy(x => x.Id).First().Id.Should().Be(15); + stores.OrderBy(x => x.Id).Last().Id.Should().Be(30); + } - [Fact] - public async Task ReturnsSecondPageOfStoreNames_GivenStoreNamesPaginatedSpec() - { - var take = 10; // pagesize 10 - var skip = (2 - 1) * 10; // page 2 + [Fact] + public async Task ReturnsSecondPageOfStoreNames_GivenStoreNamesPaginatedSpec() + { + var take = 10; // pagesize 10 + var skip = (2 - 1) * 10; // page 2 - var spec = new StoreNamesPaginatedSpec(skip, take); + var spec = new StoreNamesPaginatedSpec(skip, take); - var storeNames = await storeRepository.ListAsync(spec); + var storeNames = await storeRepository.ListAsync(spec); - storeNames.Count.Should().Be(take); - storeNames.First().Should().Be("Store 11"); - storeNames.Last().Should().Be("Store 20"); - } + storeNames.Count.Should().Be(take); + storeNames.First().Should().Be("Store 11"); + storeNames.Last().Should().Be("Store 20"); + } - [Fact] - public async Task ReturnsSecondPageOfStores_GivenStoresPaginatedSpec() - { - var take = 10; // pagesize 10 - var skip = (2 - 1) * 10; // page 2 + [Fact] + public async Task ReturnsSecondPageOfStores_GivenStoresPaginatedSpec() + { + var take = 10; // pagesize 10 + var skip = (2 - 1) * 10; // page 2 - var spec = new StoresPaginatedSpec(skip, take); - - var stores = await storeRepository.ListAsync(spec); - - stores.Count.Should().Be(take); - stores.OrderBy(x => x.Id).First().Id.Should().Be(11); - stores.OrderBy(x => x.Id).Last().Id.Should().Be(20); - } - - [Fact] - public async Task ReturnsOrderStoresByNameDescForCompanyWithId2_GivenStoresByCompanyOrderedDescByNameSpec() - { - var spec = new StoresByCompanyOrderedDescByNameSpec(2); - - var stores = await storeRepository.ListAsync(spec); - - stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_FIRST_ID); - stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_LAST_ID); - } - - [Fact] - public async Task ReturnsOrderStoresByNameDescThenByIdForCompanyWithId2_GivenStoresByCompanyOrderedDescByNameThenByIdSpec() - { - var spec = new StoresByCompanyOrderedDescByNameThenByIdSpec(2); - - var stores = await storeRepository.ListAsync(spec); - - stores.First().Id.Should().Be(99); - stores.Last().Id.Should().Be(98); - } - - [Fact] - public async Task ReturnsSecondPageOfStoresForCompanyWithId2_GivenStoresByCompanyPaginatedOrderedDescByNameSpec() - { - var take = 10; // pagesize 10 - var skip = (2 - 1) * 10; // page 2 - - var spec = new StoresByCompanyPaginatedOrderedDescByNameSpec(2, skip, take); - - var stores = await storeRepository.ListAsync(spec); - - stores.Count.Should().Be(take); - stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_PAGE2_FIRST_ID); - stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_PAGE2_LAST_ID); - } - - [Fact] - public async Task ReturnsSecondPageOfStoresForCompanyWithId2_GivenStoresByCompanyPaginatedSpec() - { - var take = 10; // pagesize 10 - var skip = (2 - 1) * 10; // page 2 - - var spec = new StoresByCompanyPaginatedSpec(2, skip, take); + var spec = new StoresPaginatedSpec(skip, take); + + var stores = await storeRepository.ListAsync(spec); + + stores.Count.Should().Be(take); + stores.OrderBy(x => x.Id).First().Id.Should().Be(11); + stores.OrderBy(x => x.Id).Last().Id.Should().Be(20); + } + + [Fact] + public async Task ReturnsOrderStoresByNameDescForCompanyWithId2_GivenStoresByCompanyOrderedDescByNameSpec() + { + var spec = new StoresByCompanyOrderedDescByNameSpec(2); + + var stores = await storeRepository.ListAsync(spec); + + stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_FIRST_ID); + stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_LAST_ID); + } + + [Fact] + public async Task ReturnsOrderStoresByNameDescThenByIdForCompanyWithId2_GivenStoresByCompanyOrderedDescByNameThenByIdSpec() + { + var spec = new StoresByCompanyOrderedDescByNameThenByIdSpec(2); + + var stores = await storeRepository.ListAsync(spec); + + stores.First().Id.Should().Be(99); + stores.Last().Id.Should().Be(98); + } + + [Fact] + public async Task ReturnsSecondPageOfStoresForCompanyWithId2_GivenStoresByCompanyPaginatedOrderedDescByNameSpec() + { + var take = 10; // pagesize 10 + var skip = (2 - 1) * 10; // page 2 + + var spec = new StoresByCompanyPaginatedOrderedDescByNameSpec(2, skip, take); + + var stores = await storeRepository.ListAsync(spec); + + stores.Count.Should().Be(take); + stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_PAGE2_FIRST_ID); + stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_PAGE2_LAST_ID); + } + + [Fact] + public async Task ReturnsSecondPageOfStoresForCompanyWithId2_GivenStoresByCompanyPaginatedSpec() + { + var take = 10; // pagesize 10 + var skip = (2 - 1) * 10; // page 2 + + var spec = new StoresByCompanyPaginatedSpec(2, skip, take); - var stores = await storeRepository.ListAsync(spec); - - stores.Count.Should().Be(take); - stores.OrderBy(x => x.Id).First().Id.Should().Be(61); - stores.OrderBy(x => x.Id).Last().Id.Should().Be(70); - } + var stores = await storeRepository.ListAsync(spec); + + stores.Count.Should().Be(take); + stores.OrderBy(x => x.Id).First().Id.Should().Be(61); + stores.OrderBy(x => x.Id).Last().Id.Should().Be(70); + } - [Fact] - public async Task ReturnsOrderedStores_GivenStoresOrderedSpecByName() - { - var spec = new StoresOrderedSpecByName(); + [Fact] + public async Task ReturnsOrderedStores_GivenStoresOrderedSpecByName() + { + var spec = new StoresOrderedSpecByName(); - var stores = await storeRepository.ListAsync(spec); + var stores = await storeRepository.ListAsync(spec); - stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_FIRST_ID); - stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_LAST_ID); - } + stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_FIRST_ID); + stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_LAST_ID); + } - [Fact] - public async Task ReturnsOrderedStores_GivenStoresOrderedDescendingByNameSpec() - { - var spec = new StoresOrderedDescendingByNameSpec(); + [Fact] + public async Task ReturnsOrderedStores_GivenStoresOrderedDescendingByNameSpec() + { + var spec = new StoresOrderedDescendingByNameSpec(); - var stores = await storeRepository.ListAsync(spec); + var stores = await storeRepository.ListAsync(spec); - stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FIRST_ID); - stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_LAST_ID); - } + stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FIRST_ID); + stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_LAST_ID); + } - [Fact] - public async Task ReturnsStoreContainingCity1_GivenStoreIncludeProductsSpec() - { - var result = await storeRepository.ListAsync(new StoreSearchByNameOrCitySpec(StoreSeed.VALID_Search_City_Key)); + [Fact] + public async Task ReturnsStoreContainingCity1_GivenStoreIncludeProductsSpec() + { + var result = await storeRepository.ListAsync(new StoreSearchByNameOrCitySpec(StoreSeed.VALID_Search_City_Key)); - result.Should().NotBeNull(); - result.Should().ContainSingle(); - result[0].Id.Should().Be(StoreSeed.VALID_Search_ID); - result[0].City.Should().Contain(StoreSeed.VALID_Search_City_Key); - } + result.Should().NotBeNull(); + result.Should().ContainSingle(); + result[0].Id.Should().Be(StoreSeed.VALID_Search_ID); + result[0].City.Should().Contain(StoreSeed.VALID_Search_City_Key); + } - [Fact] - public virtual async Task ReturnsAllProducts_GivenStoreSelectManyProductsSpec() - { - var result = await storeRepository.ListAsync(new StoreProductNamesSpec()); + [Fact] + public virtual async Task ReturnsAllProducts_GivenStoreSelectManyProductsSpec() + { + var result = await storeRepository.ListAsync(new StoreProductNamesSpec()); - result.Should().NotBeNull(); - result.Should().HaveCount(ProductSeed.TOTAL_PRODUCT_COUNT); - result.OrderBy(x => x).First().Should().Be(ProductSeed.VALID_PRODUCT_NAME); - } + result.Should().NotBeNull(); + result.Should().HaveCount(ProductSeed.TOTAL_PRODUCT_COUNT); + result.OrderBy(x => x).First().Should().Be(ProductSeed.VALID_PRODUCT_NAME); + } } diff --git a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/CachedReadConcurrentDictionary.cs b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/CachedReadConcurrentDictionary.cs index 3c2dc912..f493d7cd 100644 --- a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/CachedReadConcurrentDictionary.cs +++ b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/CachedReadConcurrentDictionary.cs @@ -12,212 +12,212 @@ namespace Ardalis.Specification.EntityFrameworkCore; /// The value type. internal class CachedReadConcurrentDictionary : IDictionary where TKey : notnull { - /// - /// The number of cache misses which are tolerated before the cache is regenerated. - /// - private const int _cacheMissesBeforeCaching = 10; - private readonly ConcurrentDictionary _dictionary; - private readonly IEqualityComparer? _comparer; - - /// - /// Approximate number of reads which did not hit the cache since it was last invalidated. - /// This is used as a heuristic that the dictionary is not being modified frequently with respect to the read volume. - /// - private int _cacheMissReads; - - /// - /// Cached version of . - /// - private Dictionary? _readCache; - - /// - /// Initializes a new instance of the class. - /// - public CachedReadConcurrentDictionary() - { - _dictionary = new ConcurrentDictionary(); - } - - /// - /// Initializes a new instance of the class - /// that contains elements copied from the specified collection. - /// - /// - /// The whose elements are copied to the new instance. - /// - public CachedReadConcurrentDictionary(IEnumerable> collection) - { - _dictionary = new ConcurrentDictionary(collection); - } - - /// - /// Initializes a new instance of the class - /// that contains elements copied from the specified collection and uses the specified - /// . - /// - /// - /// The implementation to use when comparing keys. - /// - public CachedReadConcurrentDictionary(IEqualityComparer comparer) - { - _comparer = comparer; - _dictionary = new ConcurrentDictionary(comparer); - } - - /// - /// Initializes a new instance of the - /// class that contains elements copied from the specified collection and uses the specified - /// . - /// - /// - /// The whose elements are copied to the new instance. - /// - /// - /// The implementation to use when comparing keys. - /// - public CachedReadConcurrentDictionary(IEnumerable> collection, IEqualityComparer comparer) - { - _comparer = comparer; - _dictionary = new ConcurrentDictionary(collection, comparer); - } - - /// - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - - /// - public IEnumerator> GetEnumerator() => GetReadDictionary().GetEnumerator(); - - /// - public void Add(KeyValuePair item) - { - ((IDictionary)_dictionary).Add(item); - InvalidateCache(); - } - - /// - public void Clear() - { - _dictionary.Clear(); - InvalidateCache(); - } - - /// - public bool Contains(KeyValuePair item) => GetReadDictionary().Contains(item); - - /// - public void CopyTo(KeyValuePair[] array, int arrayIndex) - { - GetReadDictionary().CopyTo(array, arrayIndex); - } - - /// - public bool Remove(KeyValuePair item) - { - var result = ((IDictionary)_dictionary).Remove(item); - if (result) InvalidateCache(); - return result; - } - - /// - public int Count => GetReadDictionary().Count; - - /// - public bool IsReadOnly => false; - - /// - public void Add(TKey key, TValue value) - { - ((IDictionary)_dictionary).Add(key, value); - InvalidateCache(); - } - - /// - /// Adds a key/value pair to the if the key does not exist. - /// - /// The key of the element to add. - /// The function used to generate a value for the key - /// The value for the key. This will be either the existing value for the key if the key is already in the dictionary, or the new value if the key was not in the dictionary. - public TValue GetOrAdd(TKey key, Func valueFactory) - { - if (GetReadDictionary().TryGetValue(key, out var value)) + /// + /// The number of cache misses which are tolerated before the cache is regenerated. + /// + private const int _cacheMissesBeforeCaching = 10; + private readonly ConcurrentDictionary _dictionary; + private readonly IEqualityComparer? _comparer; + + /// + /// Approximate number of reads which did not hit the cache since it was last invalidated. + /// This is used as a heuristic that the dictionary is not being modified frequently with respect to the read volume. + /// + private int _cacheMissReads; + + /// + /// Cached version of . + /// + private Dictionary? _readCache; + + /// + /// Initializes a new instance of the class. + /// + public CachedReadConcurrentDictionary() { - return value; + _dictionary = new ConcurrentDictionary(); } - value = _dictionary.GetOrAdd(key, valueFactory); - InvalidateCache(); - - return value; - } - - /// - /// Attempts to add the specified key and value. - /// - /// The key of the element to add. - /// The value of the element to add. The value can be a null reference (Nothing - /// in Visual Basic) for reference types. - /// true if the key/value pair was added successfully; otherwise, false. - public bool TryAdd(TKey key, TValue value) - { - if (_dictionary.TryAdd(key, value)) + /// + /// Initializes a new instance of the class + /// that contains elements copied from the specified collection. + /// + /// + /// The whose elements are copied to the new instance. + /// + public CachedReadConcurrentDictionary(IEnumerable> collection) { - InvalidateCache(); - return true; + _dictionary = new ConcurrentDictionary(collection); } - return false; - } + /// + /// Initializes a new instance of the class + /// that contains elements copied from the specified collection and uses the specified + /// . + /// + /// + /// The implementation to use when comparing keys. + /// + public CachedReadConcurrentDictionary(IEqualityComparer comparer) + { + _comparer = comparer; + _dictionary = new ConcurrentDictionary(comparer); + } - /// - public bool ContainsKey(TKey key) => GetReadDictionary().ContainsKey(key); + /// + /// Initializes a new instance of the + /// class that contains elements copied from the specified collection and uses the specified + /// . + /// + /// + /// The whose elements are copied to the new instance. + /// + /// + /// The implementation to use when comparing keys. + /// + public CachedReadConcurrentDictionary(IEnumerable> collection, IEqualityComparer comparer) + { + _comparer = comparer; + _dictionary = new ConcurrentDictionary(collection, comparer); + } - /// - public bool Remove(TKey key) - { - var result = ((IDictionary)_dictionary).Remove(key); - if (result) InvalidateCache(); - return result; - } + /// + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - /// - public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value) => GetReadDictionary().TryGetValue(key, out value); + /// + public IEnumerator> GetEnumerator() => GetReadDictionary().GetEnumerator(); - /// - public TValue this[TKey key] - { - get => GetReadDictionary()[key]; - set + /// + public void Add(KeyValuePair item) { - _dictionary[key] = value; - InvalidateCache(); + ((IDictionary)_dictionary).Add(item); + InvalidateCache(); } - } - /// - public ICollection Keys => GetReadDictionary().Keys; + /// + public void Clear() + { + _dictionary.Clear(); + InvalidateCache(); + } - /// - public ICollection Values => GetReadDictionary().Values; + /// + public bool Contains(KeyValuePair item) => GetReadDictionary().Contains(item); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private IDictionary GetReadDictionary() => _readCache ?? GetWithoutCache(); + /// + public void CopyTo(KeyValuePair[] array, int arrayIndex) + { + GetReadDictionary().CopyTo(array, arrayIndex); + } - private IDictionary GetWithoutCache() - { - // If the dictionary was recently modified or the cache is being recomputed, return the dictionary directly. - if (Interlocked.Increment(ref _cacheMissReads) < _cacheMissesBeforeCaching) + /// + public bool Remove(KeyValuePair item) { - return _dictionary; + var result = ((IDictionary)_dictionary).Remove(item); + if (result) InvalidateCache(); + return result; } - // Recompute the cache if too many cache misses have occurred. - _cacheMissReads = 0; - return _readCache = new Dictionary(_dictionary, _comparer); - } + /// + public int Count => GetReadDictionary().Count; + + /// + public bool IsReadOnly => false; + + /// + public void Add(TKey key, TValue value) + { + ((IDictionary)_dictionary).Add(key, value); + InvalidateCache(); + } + + /// + /// Adds a key/value pair to the if the key does not exist. + /// + /// The key of the element to add. + /// The function used to generate a value for the key + /// The value for the key. This will be either the existing value for the key if the key is already in the dictionary, or the new value if the key was not in the dictionary. + public TValue GetOrAdd(TKey key, Func valueFactory) + { + if (GetReadDictionary().TryGetValue(key, out var value)) + { + return value; + } + + value = _dictionary.GetOrAdd(key, valueFactory); + InvalidateCache(); + + return value; + } + + /// + /// Attempts to add the specified key and value. + /// + /// The key of the element to add. + /// The value of the element to add. The value can be a null reference (Nothing + /// in Visual Basic) for reference types. + /// true if the key/value pair was added successfully; otherwise, false. + public bool TryAdd(TKey key, TValue value) + { + if (_dictionary.TryAdd(key, value)) + { + InvalidateCache(); + return true; + } - private void InvalidateCache() - { - _cacheMissReads = 0; - _readCache = null; - } + return false; + } + + /// + public bool ContainsKey(TKey key) => GetReadDictionary().ContainsKey(key); + + /// + public bool Remove(TKey key) + { + var result = ((IDictionary)_dictionary).Remove(key); + if (result) InvalidateCache(); + return result; + } + + /// + public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value) => GetReadDictionary().TryGetValue(key, out value); + + /// + public TValue this[TKey key] + { + get => GetReadDictionary()[key]; + set + { + _dictionary[key] = value; + InvalidateCache(); + } + } + + /// + public ICollection Keys => GetReadDictionary().Keys; + + /// + public ICollection Values => GetReadDictionary().Values; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private IDictionary GetReadDictionary() => _readCache ?? GetWithoutCache(); + + private IDictionary GetWithoutCache() + { + // If the dictionary was recently modified or the cache is being recomputed, return the dictionary directly. + if (Interlocked.Increment(ref _cacheMissReads) < _cacheMissesBeforeCaching) + { + return _dictionary; + } + + // Recompute the cache if too many cache misses have occurred. + _cacheMissReads = 0; + return _readCache = new Dictionary(_dictionary, _comparer); + } + + private void InvalidateCache() + { + _cacheMissReads = 0; + _readCache = null; + } } diff --git a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/ContextFactoryRepositoryBaseOfT.cs b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/ContextFactoryRepositoryBaseOfT.cs index 7aec7b8f..7be55c15 100644 --- a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/ContextFactoryRepositoryBaseOfT.cs +++ b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/ContextFactoryRepositoryBaseOfT.cs @@ -6,223 +6,223 @@ public abstract class ContextFactoryRepositoryBaseOfT : IRepo where TEntity : class where TContext : DbContext { - private readonly IDbContextFactory _dbContextFactory; - private readonly ISpecificationEvaluator _specificationEvaluator; - - public ContextFactoryRepositoryBaseOfT(IDbContextFactory dbContextFactory) - : this(dbContextFactory, SpecificationEvaluator.Default) - { - } - - public ContextFactoryRepositoryBaseOfT(IDbContextFactory dbContextFactory, - ISpecificationEvaluator specificationEvaluator) - { - _dbContextFactory = dbContextFactory; - _specificationEvaluator = specificationEvaluator; - } - - /// - public async Task GetByIdAsync(TId id, CancellationToken cancellationToken = default) where TId : notnull - { - await using var dbContext = _dbContextFactory.CreateDbContext(); - return await dbContext.Set().FindAsync(new object[] { id }, cancellationToken: cancellationToken); - } - - /// - public async Task GetBySpecAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - await using var dbContext = _dbContextFactory.CreateDbContext(); - return await ApplySpecification(specification, dbContext).FirstOrDefaultAsync(cancellationToken); - } - - /// - public async Task GetBySpecAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - await using var dbContext = _dbContextFactory.CreateDbContext(); - return await ApplySpecification(specification, dbContext).FirstOrDefaultAsync(cancellationToken); - } - - /// - public async Task FirstOrDefaultAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - await using var dbContext = _dbContextFactory.CreateDbContext(); - return await ApplySpecification(specification, dbContext).FirstOrDefaultAsync(cancellationToken); - } - - /// - public async Task FirstOrDefaultAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - await using var dbContext = _dbContextFactory.CreateDbContext(); - return await ApplySpecification(specification, dbContext).FirstOrDefaultAsync(cancellationToken); - } - - /// - public async Task SingleOrDefaultAsync(ISingleResultSpecification specification, CancellationToken cancellationToken = default) - { - await using var dbContext = _dbContextFactory.CreateDbContext(); - return await ApplySpecification(specification, dbContext).FirstOrDefaultAsync(cancellationToken); - } - - /// - public async Task SingleOrDefaultAsync(ISingleResultSpecification specification, - CancellationToken cancellationToken = default) - { - await using var dbContext = _dbContextFactory.CreateDbContext(); - return await ApplySpecification(specification, dbContext).FirstOrDefaultAsync(cancellationToken); - } - - /// - public async Task> ListAsync(CancellationToken cancellationToken = default) - { - await using var dbContext = _dbContextFactory.CreateDbContext(); - return await dbContext.Set().ToListAsync(cancellationToken); - } - - /// - public async Task> ListAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - await using var dbContext = _dbContextFactory.CreateDbContext(); - var queryResult = await ApplySpecification(specification, dbContext).ToListAsync(cancellationToken); - - return specification.PostProcessingAction == null ? queryResult : specification.PostProcessingAction(queryResult).ToList(); - } - - /// - public async Task> ListAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - await using var dbContext = _dbContextFactory.CreateDbContext(); - var queryResult = await ApplySpecification(specification, dbContext).ToListAsync(cancellationToken); - - return specification.PostProcessingAction == null ? queryResult : specification.PostProcessingAction(queryResult).ToList(); - } - - /// - public async Task CountAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - await using var dbContext = _dbContextFactory.CreateDbContext(); - return await ApplySpecification(specification, dbContext, true).CountAsync(cancellationToken); - } - - /// - public async Task CountAsync(CancellationToken cancellationToken = default) - { - await using var dbContext = _dbContextFactory.CreateDbContext(); - return await dbContext.Set().CountAsync(cancellationToken); - } - - /// - public async Task AnyAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - await using var dbContext = _dbContextFactory.CreateDbContext(); - return await ApplySpecification(specification, dbContext, true).AnyAsync(cancellationToken); - } - - /// - public async Task AnyAsync(CancellationToken cancellationToken = default) - { - await using var dbContext = _dbContextFactory.CreateDbContext(); - return await dbContext.Set().AnyAsync(cancellationToken); - } - - /// - public IAsyncEnumerable AsAsyncEnumerable(ISpecification specification) - { - using var dbContext = _dbContextFactory.CreateDbContext(); - return ApplySpecification(specification, dbContext).AsAsyncEnumerable(); - } - - /// - public async Task AddAsync(TEntity entity, CancellationToken cancellationToken = default) - { - await using var dbContext = _dbContextFactory.CreateDbContext(); - dbContext.Set().Add(entity); - - await SaveChangesAsync(dbContext, cancellationToken); - - return entity; - } - - /// - public async Task> AddRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) - { - await using var dbContext = _dbContextFactory.CreateDbContext(); - dbContext.Set().AddRange(entities); - - await SaveChangesAsync(dbContext, cancellationToken); - - return entities; - } - - /// - public async Task UpdateAsync(TEntity entity, CancellationToken cancellationToken = default) - { - await using var dbContext = _dbContextFactory.CreateDbContext(); - dbContext.Set().Update(entity); - - await SaveChangesAsync(dbContext, cancellationToken); - } - - /// - public async Task UpdateRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) - { - await using var dbContext = _dbContextFactory.CreateDbContext(); - dbContext.Set().UpdateRange(entities); - - await SaveChangesAsync(dbContext, cancellationToken); - } - - /// - public async Task DeleteAsync(TEntity entity, CancellationToken cancellationToken = default) - { - await using var dbContext = _dbContextFactory.CreateDbContext(); - dbContext.Set().Remove(entity); - - await SaveChangesAsync(dbContext, cancellationToken); - } - - /// - public async Task DeleteRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) - { - await using var dbContext = _dbContextFactory.CreateDbContext(); - dbContext.Set().RemoveRange(entities); - - await SaveChangesAsync(dbContext, cancellationToken); - } - - /// - public Task SaveChangesAsync(CancellationToken cancellationToken = default) - { - throw new InvalidOperationException(); - } - - public async Task SaveChangesAsync(TContext dbContext, CancellationToken cancellationToken = default) - { - return await dbContext.SaveChangesAsync(cancellationToken); - } - - /// - /// Filters the entities of , to those that match the encapsulated query logic of the - /// . - /// - /// The encapsulated query logic. - /// The filtered entities as an . - protected virtual IQueryable ApplySpecification(ISpecification specification, TContext dbContext, bool evaluateCriteriaOnly = false) - { - return _specificationEvaluator.GetQuery(dbContext.Set().AsQueryable(), specification, evaluateCriteriaOnly); - } - - /// - /// Filters all entities of , that matches the encapsulated query logic of the - /// , from the database. - /// - /// Projects each entity into a new form, being . - /// - /// - /// The type of the value returned by the projection. - /// The encapsulated query logic. - /// The filtered projected entities as an . - protected virtual IQueryable ApplySpecification(ISpecification specification, TContext dbContext) - { - return _specificationEvaluator.GetQuery(dbContext.Set().AsQueryable(), specification); - } + private readonly IDbContextFactory _dbContextFactory; + private readonly ISpecificationEvaluator _specificationEvaluator; + + public ContextFactoryRepositoryBaseOfT(IDbContextFactory dbContextFactory) + : this(dbContextFactory, SpecificationEvaluator.Default) + { + } + + public ContextFactoryRepositoryBaseOfT(IDbContextFactory dbContextFactory, + ISpecificationEvaluator specificationEvaluator) + { + _dbContextFactory = dbContextFactory; + _specificationEvaluator = specificationEvaluator; + } + + /// + public async Task GetByIdAsync(TId id, CancellationToken cancellationToken = default) where TId : notnull + { + await using var dbContext = _dbContextFactory.CreateDbContext(); + return await dbContext.Set().FindAsync(new object[] { id }, cancellationToken: cancellationToken); + } + + /// + public async Task GetBySpecAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + await using var dbContext = _dbContextFactory.CreateDbContext(); + return await ApplySpecification(specification, dbContext).FirstOrDefaultAsync(cancellationToken); + } + + /// + public async Task GetBySpecAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + await using var dbContext = _dbContextFactory.CreateDbContext(); + return await ApplySpecification(specification, dbContext).FirstOrDefaultAsync(cancellationToken); + } + + /// + public async Task FirstOrDefaultAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + await using var dbContext = _dbContextFactory.CreateDbContext(); + return await ApplySpecification(specification, dbContext).FirstOrDefaultAsync(cancellationToken); + } + + /// + public async Task FirstOrDefaultAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + await using var dbContext = _dbContextFactory.CreateDbContext(); + return await ApplySpecification(specification, dbContext).FirstOrDefaultAsync(cancellationToken); + } + + /// + public async Task SingleOrDefaultAsync(ISingleResultSpecification specification, CancellationToken cancellationToken = default) + { + await using var dbContext = _dbContextFactory.CreateDbContext(); + return await ApplySpecification(specification, dbContext).FirstOrDefaultAsync(cancellationToken); + } + + /// + public async Task SingleOrDefaultAsync(ISingleResultSpecification specification, + CancellationToken cancellationToken = default) + { + await using var dbContext = _dbContextFactory.CreateDbContext(); + return await ApplySpecification(specification, dbContext).FirstOrDefaultAsync(cancellationToken); + } + + /// + public async Task> ListAsync(CancellationToken cancellationToken = default) + { + await using var dbContext = _dbContextFactory.CreateDbContext(); + return await dbContext.Set().ToListAsync(cancellationToken); + } + + /// + public async Task> ListAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + await using var dbContext = _dbContextFactory.CreateDbContext(); + var queryResult = await ApplySpecification(specification, dbContext).ToListAsync(cancellationToken); + + return specification.PostProcessingAction == null ? queryResult : specification.PostProcessingAction(queryResult).ToList(); + } + + /// + public async Task> ListAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + await using var dbContext = _dbContextFactory.CreateDbContext(); + var queryResult = await ApplySpecification(specification, dbContext).ToListAsync(cancellationToken); + + return specification.PostProcessingAction == null ? queryResult : specification.PostProcessingAction(queryResult).ToList(); + } + + /// + public async Task CountAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + await using var dbContext = _dbContextFactory.CreateDbContext(); + return await ApplySpecification(specification, dbContext, true).CountAsync(cancellationToken); + } + + /// + public async Task CountAsync(CancellationToken cancellationToken = default) + { + await using var dbContext = _dbContextFactory.CreateDbContext(); + return await dbContext.Set().CountAsync(cancellationToken); + } + + /// + public async Task AnyAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + await using var dbContext = _dbContextFactory.CreateDbContext(); + return await ApplySpecification(specification, dbContext, true).AnyAsync(cancellationToken); + } + + /// + public async Task AnyAsync(CancellationToken cancellationToken = default) + { + await using var dbContext = _dbContextFactory.CreateDbContext(); + return await dbContext.Set().AnyAsync(cancellationToken); + } + + /// + public IAsyncEnumerable AsAsyncEnumerable(ISpecification specification) + { + using var dbContext = _dbContextFactory.CreateDbContext(); + return ApplySpecification(specification, dbContext).AsAsyncEnumerable(); + } + + /// + public async Task AddAsync(TEntity entity, CancellationToken cancellationToken = default) + { + await using var dbContext = _dbContextFactory.CreateDbContext(); + dbContext.Set().Add(entity); + + await SaveChangesAsync(dbContext, cancellationToken); + + return entity; + } + + /// + public async Task> AddRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) + { + await using var dbContext = _dbContextFactory.CreateDbContext(); + dbContext.Set().AddRange(entities); + + await SaveChangesAsync(dbContext, cancellationToken); + + return entities; + } + + /// + public async Task UpdateAsync(TEntity entity, CancellationToken cancellationToken = default) + { + await using var dbContext = _dbContextFactory.CreateDbContext(); + dbContext.Set().Update(entity); + + await SaveChangesAsync(dbContext, cancellationToken); + } + + /// + public async Task UpdateRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) + { + await using var dbContext = _dbContextFactory.CreateDbContext(); + dbContext.Set().UpdateRange(entities); + + await SaveChangesAsync(dbContext, cancellationToken); + } + + /// + public async Task DeleteAsync(TEntity entity, CancellationToken cancellationToken = default) + { + await using var dbContext = _dbContextFactory.CreateDbContext(); + dbContext.Set().Remove(entity); + + await SaveChangesAsync(dbContext, cancellationToken); + } + + /// + public async Task DeleteRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) + { + await using var dbContext = _dbContextFactory.CreateDbContext(); + dbContext.Set().RemoveRange(entities); + + await SaveChangesAsync(dbContext, cancellationToken); + } + + /// + public Task SaveChangesAsync(CancellationToken cancellationToken = default) + { + throw new InvalidOperationException(); + } + + public async Task SaveChangesAsync(TContext dbContext, CancellationToken cancellationToken = default) + { + return await dbContext.SaveChangesAsync(cancellationToken); + } + + /// + /// Filters the entities of , to those that match the encapsulated query logic of the + /// . + /// + /// The encapsulated query logic. + /// The filtered entities as an . + protected virtual IQueryable ApplySpecification(ISpecification specification, TContext dbContext, bool evaluateCriteriaOnly = false) + { + return _specificationEvaluator.GetQuery(dbContext.Set().AsQueryable(), specification, evaluateCriteriaOnly); + } + + /// + /// Filters all entities of , that matches the encapsulated query logic of the + /// , from the database. + /// + /// Projects each entity into a new form, being . + /// + /// + /// The type of the value returned by the projection. + /// The encapsulated query logic. + /// The filtered projected entities as an . + protected virtual IQueryable ApplySpecification(ISpecification specification, TContext dbContext) + { + return _specificationEvaluator.GetQuery(dbContext.Set().AsQueryable(), specification); + } } diff --git a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/EFRepositoryFactory.cs b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/EFRepositoryFactory.cs index 8f5c970e..3e21e647 100644 --- a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/EFRepositoryFactory.cs +++ b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/EFRepositoryFactory.cs @@ -14,21 +14,21 @@ public class EFRepositoryFactory : I where TConcreteRepository : TRepository where TContext : DbContext { - private readonly IDbContextFactory _dbContextFactory; + private readonly IDbContextFactory _dbContextFactory; - /// - /// Initialises a new instance of the EFRepositoryFactory - /// - /// The IDbContextFactory to use to generate the TContext - public EFRepositoryFactory(IDbContextFactory dbContextFactory) - { - _dbContextFactory = dbContextFactory; - } + /// + /// Initialises a new instance of the EFRepositoryFactory + /// + /// The IDbContextFactory to use to generate the TContext + public EFRepositoryFactory(IDbContextFactory dbContextFactory) + { + _dbContextFactory = dbContextFactory; + } - /// - public TRepository CreateRepository() - { - var args = new object[] { _dbContextFactory.CreateDbContext() }; - return (TRepository)Activator.CreateInstance(typeof(TConcreteRepository), args)!; - } + /// + public TRepository CreateRepository() + { + var args = new object[] { _dbContextFactory.CreateDbContext() }; + return (TRepository)Activator.CreateInstance(typeof(TConcreteRepository), args)!; + } } diff --git a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/AsNoTrackingEvaluator.cs b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/AsNoTrackingEvaluator.cs index 561b62c8..7859f23a 100644 --- a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/AsNoTrackingEvaluator.cs +++ b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/AsNoTrackingEvaluator.cs @@ -4,18 +4,18 @@ namespace Ardalis.Specification.EntityFrameworkCore; public class AsNoTrackingEvaluator : IEvaluator { - private AsNoTrackingEvaluator() { } - public static AsNoTrackingEvaluator Instance { get; } = new AsNoTrackingEvaluator(); + private AsNoTrackingEvaluator() { } + public static AsNoTrackingEvaluator Instance { get; } = new AsNoTrackingEvaluator(); - public bool IsCriteriaEvaluator { get; } = true; + public bool IsCriteriaEvaluator { get; } = true; - public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class - { - if (specification.AsNoTracking) + public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class { - query = query.AsNoTracking(); - } + if (specification.AsNoTracking) + { + query = query.AsNoTracking(); + } - return query; - } + return query; + } } diff --git a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/AsNoTrackingWithIdentityResolutionEvaluator.cs b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/AsNoTrackingWithIdentityResolutionEvaluator.cs index c2292e66..0db45cd0 100644 --- a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/AsNoTrackingWithIdentityResolutionEvaluator.cs +++ b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/AsNoTrackingWithIdentityResolutionEvaluator.cs @@ -4,18 +4,18 @@ namespace Ardalis.Specification.EntityFrameworkCore; public class AsNoTrackingWithIdentityResolutionEvaluator : IEvaluator { - private AsNoTrackingWithIdentityResolutionEvaluator() { } - public static AsNoTrackingWithIdentityResolutionEvaluator Instance { get; } = new AsNoTrackingWithIdentityResolutionEvaluator(); + private AsNoTrackingWithIdentityResolutionEvaluator() { } + public static AsNoTrackingWithIdentityResolutionEvaluator Instance { get; } = new AsNoTrackingWithIdentityResolutionEvaluator(); - public bool IsCriteriaEvaluator { get; } = true; + public bool IsCriteriaEvaluator { get; } = true; - public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class - { - if (specification.AsNoTrackingWithIdentityResolution) + public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class { - query = query.AsNoTrackingWithIdentityResolution(); - } + if (specification.AsNoTrackingWithIdentityResolution) + { + query = query.AsNoTrackingWithIdentityResolution(); + } - return query; - } + return query; + } } diff --git a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/AsSplitQueryEvaluator.cs b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/AsSplitQueryEvaluator.cs index 5b2943bb..f50800f6 100644 --- a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/AsSplitQueryEvaluator.cs +++ b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/AsSplitQueryEvaluator.cs @@ -4,18 +4,18 @@ namespace Ardalis.Specification.EntityFrameworkCore; public class AsSplitQueryEvaluator : IEvaluator { - private AsSplitQueryEvaluator() { } - public static AsSplitQueryEvaluator Instance { get; } = new AsSplitQueryEvaluator(); + private AsSplitQueryEvaluator() { } + public static AsSplitQueryEvaluator Instance { get; } = new AsSplitQueryEvaluator(); - public bool IsCriteriaEvaluator { get; } = true; + public bool IsCriteriaEvaluator { get; } = true; - public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class - { - if (specification.AsSplitQuery) + public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class { - query = query.AsSplitQuery(); - } + if (specification.AsSplitQuery) + { + query = query.AsSplitQuery(); + } - return query; - } + return query; + } } diff --git a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/AsTrackingEvaluator.cs b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/AsTrackingEvaluator.cs index 91af9528..1af2b43d 100644 --- a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/AsTrackingEvaluator.cs +++ b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/AsTrackingEvaluator.cs @@ -4,18 +4,18 @@ namespace Ardalis.Specification.EntityFrameworkCore; public class AsTrackingEvaluator : IEvaluator { - private AsTrackingEvaluator() { } - public static AsTrackingEvaluator Instance { get; } = new AsTrackingEvaluator(); + private AsTrackingEvaluator() { } + public static AsTrackingEvaluator Instance { get; } = new AsTrackingEvaluator(); - public bool IsCriteriaEvaluator { get; } = true; + public bool IsCriteriaEvaluator { get; } = true; - public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class - { - if (specification.AsTracking) + public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class { - query = query.AsTracking(); - } + if (specification.AsTracking) + { + query = query.AsTracking(); + } - return query; - } + return query; + } } diff --git a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/IgnoreQueryFiltersEvaluator.cs b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/IgnoreQueryFiltersEvaluator.cs index d122bbfd..91db6db5 100644 --- a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/IgnoreQueryFiltersEvaluator.cs +++ b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/IgnoreQueryFiltersEvaluator.cs @@ -8,18 +8,18 @@ namespace Ardalis.Specification.EntityFrameworkCore; /// public class IgnoreQueryFiltersEvaluator : IEvaluator { - private IgnoreQueryFiltersEvaluator() { } - public static IgnoreQueryFiltersEvaluator Instance { get; } = new IgnoreQueryFiltersEvaluator(); + private IgnoreQueryFiltersEvaluator() { } + public static IgnoreQueryFiltersEvaluator Instance { get; } = new IgnoreQueryFiltersEvaluator(); - public bool IsCriteriaEvaluator { get; } = true; + public bool IsCriteriaEvaluator { get; } = true; - public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class - { - if (specification.IgnoreQueryFilters) + public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class { - query = query.IgnoreQueryFilters(); - } + if (specification.IgnoreQueryFilters) + { + query = query.IgnoreQueryFilters(); + } - return query; - } + return query; + } } diff --git a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/IncludeEvaluator.cs b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/IncludeEvaluator.cs index bb54814b..2a42bfce 100644 --- a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/IncludeEvaluator.cs +++ b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/IncludeEvaluator.cs @@ -7,182 +7,182 @@ namespace Ardalis.Specification.EntityFrameworkCore; public class IncludeEvaluator : IEvaluator { - private static readonly MethodInfo _includeMethodInfo = typeof(EntityFrameworkQueryableExtensions) - .GetTypeInfo().GetDeclaredMethods(nameof(EntityFrameworkQueryableExtensions.Include)) - .Single(mi => mi.GetGenericArguments().Length == 2 - && mi.GetParameters()[0].ParameterType.GetGenericTypeDefinition() == typeof(IQueryable<>) - && mi.GetParameters()[1].ParameterType.GetGenericTypeDefinition() == typeof(Expression<>)); - - private static readonly MethodInfo _thenIncludeAfterReferenceMethodInfo - = typeof(EntityFrameworkQueryableExtensions) - .GetTypeInfo().GetDeclaredMethods(nameof(EntityFrameworkQueryableExtensions.ThenInclude)) - .Single(mi => mi.GetGenericArguments().Length == 3 - && mi.GetParameters()[0].ParameterType.GenericTypeArguments[1].IsGenericParameter - && mi.GetParameters()[0].ParameterType.GetGenericTypeDefinition() == typeof(IIncludableQueryable<,>) - && mi.GetParameters()[1].ParameterType.GetGenericTypeDefinition() == typeof(Expression<>)); - - private static readonly MethodInfo _thenIncludeAfterEnumerableMethodInfo - = typeof(EntityFrameworkQueryableExtensions) - .GetTypeInfo().GetDeclaredMethods(nameof(EntityFrameworkQueryableExtensions.ThenInclude)) - .Where(mi => mi.GetGenericArguments().Length == 3) - .Single( - mi => - { - var typeInfo = mi.GetParameters()[0].ParameterType.GenericTypeArguments[1]; - - return typeInfo.IsGenericType - && typeInfo.GetGenericTypeDefinition() == typeof(IEnumerable<>) - && mi.GetParameters()[0].ParameterType.GetGenericTypeDefinition() == typeof(IIncludableQueryable<,>) - && mi.GetParameters()[1].ParameterType.GetGenericTypeDefinition() == typeof(Expression<>); - }); - - private static readonly CachedReadConcurrentDictionary<(Type EntityType, Type PropertyType, Type? PreviousPropertyType), Lazy>> _delegatesCache = new(); - - private readonly bool _cacheEnabled; - - private IncludeEvaluator(bool cacheEnabled) - { - _cacheEnabled = cacheEnabled; - } - - /// - /// instance without any additional features. - /// - public static IncludeEvaluator Default { get; } = new IncludeEvaluator(false); - - /// - /// instance with caching to provide better performance. - /// - public static IncludeEvaluator Cached { get; } = new IncludeEvaluator(true); - - public bool IsCriteriaEvaluator => false; - - public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class - { - foreach (var includeString in specification.IncludeStrings) + private static readonly MethodInfo _includeMethodInfo = typeof(EntityFrameworkQueryableExtensions) + .GetTypeInfo().GetDeclaredMethods(nameof(EntityFrameworkQueryableExtensions.Include)) + .Single(mi => mi.GetGenericArguments().Length == 2 + && mi.GetParameters()[0].ParameterType.GetGenericTypeDefinition() == typeof(IQueryable<>) + && mi.GetParameters()[1].ParameterType.GetGenericTypeDefinition() == typeof(Expression<>)); + + private static readonly MethodInfo _thenIncludeAfterReferenceMethodInfo + = typeof(EntityFrameworkQueryableExtensions) + .GetTypeInfo().GetDeclaredMethods(nameof(EntityFrameworkQueryableExtensions.ThenInclude)) + .Single(mi => mi.GetGenericArguments().Length == 3 + && mi.GetParameters()[0].ParameterType.GenericTypeArguments[1].IsGenericParameter + && mi.GetParameters()[0].ParameterType.GetGenericTypeDefinition() == typeof(IIncludableQueryable<,>) + && mi.GetParameters()[1].ParameterType.GetGenericTypeDefinition() == typeof(Expression<>)); + + private static readonly MethodInfo _thenIncludeAfterEnumerableMethodInfo + = typeof(EntityFrameworkQueryableExtensions) + .GetTypeInfo().GetDeclaredMethods(nameof(EntityFrameworkQueryableExtensions.ThenInclude)) + .Where(mi => mi.GetGenericArguments().Length == 3) + .Single( + mi => + { + var typeInfo = mi.GetParameters()[0].ParameterType.GenericTypeArguments[1]; + + return typeInfo.IsGenericType + && typeInfo.GetGenericTypeDefinition() == typeof(IEnumerable<>) + && mi.GetParameters()[0].ParameterType.GetGenericTypeDefinition() == typeof(IIncludableQueryable<,>) + && mi.GetParameters()[1].ParameterType.GetGenericTypeDefinition() == typeof(Expression<>); + }); + + private static readonly CachedReadConcurrentDictionary<(Type EntityType, Type PropertyType, Type? PreviousPropertyType), Lazy>> _delegatesCache = new(); + + private readonly bool _cacheEnabled; + + private IncludeEvaluator(bool cacheEnabled) { - query = query.Include(includeString); + _cacheEnabled = cacheEnabled; } - foreach (var includeInfo in specification.IncludeExpressions) - { - if (includeInfo.Type == IncludeTypeEnum.Include) - { - query = BuildInclude(query, includeInfo); - } - else if (includeInfo.Type == IncludeTypeEnum.ThenInclude) - { - query = BuildThenInclude(query, includeInfo); - } - } + /// + /// instance without any additional features. + /// + public static IncludeEvaluator Default { get; } = new IncludeEvaluator(false); - return query; - } + /// + /// instance with caching to provide better performance. + /// + public static IncludeEvaluator Cached { get; } = new IncludeEvaluator(true); - private IQueryable BuildInclude(IQueryable query, IncludeExpressionInfo includeInfo) - { - _ = includeInfo ?? throw new ArgumentNullException(nameof(includeInfo)); + public bool IsCriteriaEvaluator => false; - if (!_cacheEnabled) + public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class { - var result = _includeMethodInfo.MakeGenericMethod(includeInfo.EntityType, includeInfo.PropertyType).Invoke(null, new object[] { query, includeInfo.LambdaExpression }); + foreach (var includeString in specification.IncludeStrings) + { + query = query.Include(includeString); + } - _ = result ?? throw new TargetException(); + foreach (var includeInfo in specification.IncludeExpressions) + { + if (includeInfo.Type == IncludeTypeEnum.Include) + { + query = BuildInclude(query, includeInfo); + } + else if (includeInfo.Type == IncludeTypeEnum.ThenInclude) + { + query = BuildThenInclude(query, includeInfo); + } + } - return (IQueryable)result; + return query; } - var include = _delegatesCache.GetOrAdd((includeInfo.EntityType, includeInfo.PropertyType, null), CreateIncludeDelegate).Value; + private IQueryable BuildInclude(IQueryable query, IncludeExpressionInfo includeInfo) + { + _ = includeInfo ?? throw new ArgumentNullException(nameof(includeInfo)); - return (IQueryable)include(query, includeInfo.LambdaExpression); - } + if (!_cacheEnabled) + { + var result = _includeMethodInfo.MakeGenericMethod(includeInfo.EntityType, includeInfo.PropertyType).Invoke(null, new object[] { query, includeInfo.LambdaExpression }); - private IQueryable BuildThenInclude(IQueryable query, IncludeExpressionInfo includeInfo) - { - _ = includeInfo ?? throw new ArgumentNullException(nameof(includeInfo)); - _ = includeInfo.PreviousPropertyType ?? throw new ArgumentNullException(nameof(includeInfo.PreviousPropertyType)); + _ = result ?? throw new TargetException(); - if (!_cacheEnabled) - { - var result = (IsGenericEnumerable(includeInfo.PreviousPropertyType, out var previousPropertyType) - ? _thenIncludeAfterEnumerableMethodInfo - : _thenIncludeAfterReferenceMethodInfo).MakeGenericMethod(includeInfo.EntityType, previousPropertyType, includeInfo.PropertyType) - .Invoke(null, new object[] { query, includeInfo.LambdaExpression, }); + return (IQueryable)result; + } - _ = result ?? throw new TargetException(); + var include = _delegatesCache.GetOrAdd((includeInfo.EntityType, includeInfo.PropertyType, null), CreateIncludeDelegate).Value; - return (IQueryable)result; + return (IQueryable)include(query, includeInfo.LambdaExpression); } - var thenInclude = _delegatesCache.GetOrAdd((includeInfo.EntityType, includeInfo.PropertyType, includeInfo.PreviousPropertyType), CreateThenIncludeDelegate).Value; - - return (IQueryable)thenInclude(query, includeInfo.LambdaExpression); - } - - // (source, selector) => EntityFrameworkQueryableExtensions.Include((IQueryable)source, (Expression>)selector); - private static Lazy> CreateIncludeDelegate((Type EntityType, Type PropertyType, Type? PreviousPropertyType) cacheKey) - => new(() => - { - var concreteInclude = _includeMethodInfo.MakeGenericMethod(cacheKey.EntityType, cacheKey.PropertyType); - var sourceParameter = Expression.Parameter(typeof(IQueryable)); - var selectorParameter = Expression.Parameter(typeof(LambdaExpression)); - - var call = Expression.Call( - concreteInclude, - Expression.Convert(sourceParameter, typeof(IQueryable<>).MakeGenericType(cacheKey.EntityType)), - Expression.Convert(selectorParameter, typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(cacheKey.EntityType, cacheKey.PropertyType)))); - - var lambda = Expression.Lambda>(call, sourceParameter, selectorParameter); - - return lambda.Compile(); - }); - - // ((source, selector) => - // EntityFrameworkQueryableExtensions.ThenInclude( - // (IIncludableQueryable)source, - // (Expression>)selector); - // (source, selector) => - // EntityFrameworkQueryableExtensions.ThenInclude( - // (IIncludableQueryable>)source, - // (Expression>)selector); - private static Lazy> CreateThenIncludeDelegate((Type EntityType, Type PropertyType, Type? PreviousPropertyType) cacheKey) - => new(() => - { - _ = cacheKey.PreviousPropertyType ?? throw new ArgumentNullException(nameof(cacheKey.PreviousPropertyType)); - - var thenIncludeInfo = _thenIncludeAfterReferenceMethodInfo; - if (IsGenericEnumerable(cacheKey.PreviousPropertyType, out var previousPropertyType)) + private IQueryable BuildThenInclude(IQueryable query, IncludeExpressionInfo includeInfo) + { + _ = includeInfo ?? throw new ArgumentNullException(nameof(includeInfo)); + _ = includeInfo.PreviousPropertyType ?? throw new ArgumentNullException(nameof(includeInfo.PreviousPropertyType)); + + if (!_cacheEnabled) { - thenIncludeInfo = _thenIncludeAfterEnumerableMethodInfo; + var result = (IsGenericEnumerable(includeInfo.PreviousPropertyType, out var previousPropertyType) + ? _thenIncludeAfterEnumerableMethodInfo + : _thenIncludeAfterReferenceMethodInfo).MakeGenericMethod(includeInfo.EntityType, previousPropertyType, includeInfo.PropertyType) + .Invoke(null, new object[] { query, includeInfo.LambdaExpression, }); + + _ = result ?? throw new TargetException(); + + return (IQueryable)result; } - var concreteThenInclude = thenIncludeInfo.MakeGenericMethod(cacheKey.EntityType, previousPropertyType, cacheKey.PropertyType); - var sourceParameter = Expression.Parameter(typeof(IQueryable)); - var selectorParameter = Expression.Parameter(typeof(LambdaExpression)); + var thenInclude = _delegatesCache.GetOrAdd((includeInfo.EntityType, includeInfo.PropertyType, includeInfo.PreviousPropertyType), CreateThenIncludeDelegate).Value; + + return (IQueryable)thenInclude(query, includeInfo.LambdaExpression); + } + + // (source, selector) => EntityFrameworkQueryableExtensions.Include((IQueryable)source, (Expression>)selector); + private static Lazy> CreateIncludeDelegate((Type EntityType, Type PropertyType, Type? PreviousPropertyType) cacheKey) + => new(() => + { + var concreteInclude = _includeMethodInfo.MakeGenericMethod(cacheKey.EntityType, cacheKey.PropertyType); + var sourceParameter = Expression.Parameter(typeof(IQueryable)); + var selectorParameter = Expression.Parameter(typeof(LambdaExpression)); + + var call = Expression.Call( + concreteInclude, + Expression.Convert(sourceParameter, typeof(IQueryable<>).MakeGenericType(cacheKey.EntityType)), + Expression.Convert(selectorParameter, typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(cacheKey.EntityType, cacheKey.PropertyType)))); + + var lambda = Expression.Lambda>(call, sourceParameter, selectorParameter); + + return lambda.Compile(); + }); + + // ((source, selector) => + // EntityFrameworkQueryableExtensions.ThenInclude( + // (IIncludableQueryable)source, + // (Expression>)selector); + // (source, selector) => + // EntityFrameworkQueryableExtensions.ThenInclude( + // (IIncludableQueryable>)source, + // (Expression>)selector); + private static Lazy> CreateThenIncludeDelegate((Type EntityType, Type PropertyType, Type? PreviousPropertyType) cacheKey) + => new(() => + { + _ = cacheKey.PreviousPropertyType ?? throw new ArgumentNullException(nameof(cacheKey.PreviousPropertyType)); + + var thenIncludeInfo = _thenIncludeAfterReferenceMethodInfo; + if (IsGenericEnumerable(cacheKey.PreviousPropertyType, out var previousPropertyType)) + { + thenIncludeInfo = _thenIncludeAfterEnumerableMethodInfo; + } + + var concreteThenInclude = thenIncludeInfo.MakeGenericMethod(cacheKey.EntityType, previousPropertyType, cacheKey.PropertyType); + var sourceParameter = Expression.Parameter(typeof(IQueryable)); + var selectorParameter = Expression.Parameter(typeof(LambdaExpression)); - var call = Expression.Call( - concreteThenInclude, - Expression.Convert( - sourceParameter, - typeof(IIncludableQueryable<,>).MakeGenericType(cacheKey.EntityType, cacheKey.PreviousPropertyType)), // cacheKey.PreviousPropertyType must be exact type, not generic type argument - Expression.Convert(selectorParameter, typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(previousPropertyType, cacheKey.PropertyType)))); + var call = Expression.Call( + concreteThenInclude, + Expression.Convert( + sourceParameter, + typeof(IIncludableQueryable<,>).MakeGenericType(cacheKey.EntityType, cacheKey.PreviousPropertyType)), // cacheKey.PreviousPropertyType must be exact type, not generic type argument + Expression.Convert(selectorParameter, typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(previousPropertyType, cacheKey.PropertyType)))); - var lambda = Expression.Lambda>(call, sourceParameter, selectorParameter); + var lambda = Expression.Lambda>(call, sourceParameter, selectorParameter); - return lambda.Compile(); - }); + return lambda.Compile(); + }); - private static bool IsGenericEnumerable(Type type, out Type propertyType) - { - if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable<>)) + private static bool IsGenericEnumerable(Type type, out Type propertyType) { - propertyType = type.GenericTypeArguments[0]; + if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable<>)) + { + propertyType = type.GenericTypeArguments[0]; - return true; - } + return true; + } - propertyType = type; + propertyType = type; - return false; - } + return false; + } } diff --git a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/SearchEvaluator.cs b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/SearchEvaluator.cs index 3f0960fc..a5bbf0af 100644 --- a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/SearchEvaluator.cs +++ b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/SearchEvaluator.cs @@ -2,18 +2,18 @@ public class SearchEvaluator : IEvaluator { - private SearchEvaluator() { } - public static SearchEvaluator Instance { get; } = new SearchEvaluator(); + private SearchEvaluator() { } + public static SearchEvaluator Instance { get; } = new SearchEvaluator(); - public bool IsCriteriaEvaluator { get; } = true; + public bool IsCriteriaEvaluator { get; } = true; - public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class - { - foreach (var searchCriteria in specification.SearchCriterias.GroupBy(x => x.SearchGroup)) + public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class { - query = query.Search(searchCriteria); - } + foreach (var searchCriteria in specification.SearchCriterias.GroupBy(x => x.SearchGroup)) + { + query = query.Search(searchCriteria); + } - return query; - } + 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 5ebb6763..5434ac11 100644 --- a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/SpecificationEvaluator.cs +++ b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Evaluators/SpecificationEvaluator.cs @@ -3,67 +3,67 @@ /// public class SpecificationEvaluator : ISpecificationEvaluator { - // Will use singleton for default configuration. Yet, it can be instantiated if necessary, with default or provided evaluators. - /// - /// instance with default evaluators and without any additional features enabled. - /// - public static SpecificationEvaluator Default { get; } = new SpecificationEvaluator(); + // Will use singleton for default configuration. Yet, it can be instantiated if necessary, with default or provided evaluators. + /// + /// instance with default evaluators and without any additional features enabled. + /// + public static SpecificationEvaluator Default { get; } = new SpecificationEvaluator(); - /// - /// instance with default evaluators and enabled caching. - /// - public static SpecificationEvaluator Cached { get; } = new SpecificationEvaluator(true); + /// + /// instance with default evaluators and enabled caching. + /// + public static SpecificationEvaluator Cached { get; } = new SpecificationEvaluator(true); - protected List Evaluators { get; } = new List(); + protected List Evaluators { get; } = new List(); - public SpecificationEvaluator(bool cacheEnabled = false) - { - Evaluators.AddRange(new IEvaluator[] + public SpecificationEvaluator(bool cacheEnabled = false) { - WhereEvaluator.Instance, - SearchEvaluator.Instance, - cacheEnabled ? IncludeEvaluator.Cached : IncludeEvaluator.Default, - OrderEvaluator.Instance, - PaginationEvaluator.Instance, - AsNoTrackingEvaluator.Instance, - AsNoTrackingWithIdentityResolutionEvaluator.Instance, - AsTrackingEvaluator.Instance, - IgnoreQueryFiltersEvaluator.Instance, - AsSplitQueryEvaluator.Instance - }); - } + Evaluators.AddRange(new IEvaluator[] + { + WhereEvaluator.Instance, + SearchEvaluator.Instance, + cacheEnabled ? IncludeEvaluator.Cached : IncludeEvaluator.Default, + OrderEvaluator.Instance, + PaginationEvaluator.Instance, + AsNoTrackingEvaluator.Instance, + AsNoTrackingWithIdentityResolutionEvaluator.Instance, + AsTrackingEvaluator.Instance, + IgnoreQueryFiltersEvaluator.Instance, + AsSplitQueryEvaluator.Instance + }); + } - public SpecificationEvaluator(IEnumerable evaluators) - { - Evaluators.AddRange(evaluators); - } + public SpecificationEvaluator(IEnumerable evaluators) + { + Evaluators.AddRange(evaluators); + } - /// - public virtual IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class - { - if (specification is null) throw new ArgumentNullException(nameof(specification)); - if (specification.Selector is null && specification.SelectorMany is null) throw new SelectorNotFoundException(); - if (specification.Selector is not null && specification.SelectorMany is not null) throw new ConcurrentSelectorsException(); + /// + public virtual IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class + { + if (specification is null) throw new ArgumentNullException(nameof(specification)); + if (specification.Selector is null && specification.SelectorMany is null) throw new SelectorNotFoundException(); + if (specification.Selector is not null && specification.SelectorMany is not null) throw new ConcurrentSelectorsException(); - query = GetQuery(query, (ISpecification)specification); + query = GetQuery(query, (ISpecification)specification); - return specification.Selector is not null - ? query.Select(specification.Selector) - : query.SelectMany(specification.SelectorMany!); - } + return specification.Selector is not null + ? query.Select(specification.Selector) + : query.SelectMany(specification.SelectorMany!); + } - /// - public virtual IQueryable GetQuery(IQueryable query, ISpecification specification, bool evaluateCriteriaOnly = false) where T : class - { - if (specification is null) throw new ArgumentNullException(nameof(specification)); + /// + public virtual IQueryable GetQuery(IQueryable query, ISpecification specification, bool evaluateCriteriaOnly = false) where T : class + { + if (specification is null) throw new ArgumentNullException(nameof(specification)); - var evaluators = evaluateCriteriaOnly ? Evaluators.Where(x => x.IsCriteriaEvaluator) : Evaluators; + var evaluators = evaluateCriteriaOnly ? Evaluators.Where(x => x.IsCriteriaEvaluator) : Evaluators; - foreach (var evaluator in evaluators) - { - query = evaluator.GetQuery(query, specification); - } + foreach (var evaluator in evaluators) + { + query = evaluator.GetQuery(query, specification); + } - return query; - } + return query; + } } diff --git a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Extensions/DbSetExtensions.cs b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Extensions/DbSetExtensions.cs index c54b7ddb..e0c9e197 100644 --- a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Extensions/DbSetExtensions.cs +++ b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Extensions/DbSetExtensions.cs @@ -4,49 +4,49 @@ namespace Ardalis.Specification.EntityFrameworkCore; public static class DbSetExtensions { - public static async Task> ToListAsync( - this DbSet source, - ISpecification specification, - CancellationToken cancellationToken = default) - where TSource : class - { - var result = await SpecificationEvaluator.Default.GetQuery(source, specification).ToListAsync(cancellationToken); + public static async Task> ToListAsync( + this DbSet source, + ISpecification specification, + CancellationToken cancellationToken = default) + where TSource : class + { + var result = await SpecificationEvaluator.Default.GetQuery(source, specification).ToListAsync(cancellationToken); - return specification.PostProcessingAction == null - ? result - : specification.PostProcessingAction(result).ToList(); - } + return specification.PostProcessingAction == null + ? result + : specification.PostProcessingAction(result).ToList(); + } - public static async Task> ToEnumerableAsync( - this DbSet source, - ISpecification specification, - CancellationToken cancellationToken = default) - where TSource : class - { - var result = await SpecificationEvaluator.Default.GetQuery(source, specification).ToListAsync(cancellationToken); + public static async Task> ToEnumerableAsync( + this DbSet source, + ISpecification specification, + CancellationToken cancellationToken = default) + where TSource : class + { + var result = await SpecificationEvaluator.Default.GetQuery(source, specification).ToListAsync(cancellationToken); - return specification.PostProcessingAction == null - ? result - : specification.PostProcessingAction(result); - } + return specification.PostProcessingAction == null + ? result + : specification.PostProcessingAction(result); + } - public static IQueryable WithSpecification( - this IQueryable source, - ISpecification specification, - ISpecificationEvaluator? evaluator = null) - where TSource : class - { - evaluator ??= SpecificationEvaluator.Default; - return evaluator.GetQuery(source, specification); - } + public static IQueryable WithSpecification( + this IQueryable source, + ISpecification specification, + ISpecificationEvaluator? evaluator = null) + where TSource : class + { + evaluator ??= SpecificationEvaluator.Default; + return evaluator.GetQuery(source, specification); + } - public static IQueryable WithSpecification( - this IQueryable source, - ISpecification specification, - ISpecificationEvaluator? evaluator = null) - where TSource : class - { - evaluator ??= SpecificationEvaluator.Default; - return evaluator.GetQuery(source, specification); - } + public static IQueryable WithSpecification( + this IQueryable source, + ISpecification specification, + ISpecificationEvaluator? evaluator = null) + where TSource : class + { + evaluator ??= SpecificationEvaluator.Default; + return evaluator.GetQuery(source, specification); + } } diff --git a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Extensions/ParameterReplacerVisitor.cs b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Extensions/ParameterReplacerVisitor.cs index 655bc721..74823678 100644 --- a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Extensions/ParameterReplacerVisitor.cs +++ b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Extensions/ParameterReplacerVisitor.cs @@ -4,18 +4,18 @@ namespace Ardalis.Specification.EntityFrameworkCore; internal class ParameterReplacerVisitor : ExpressionVisitor { - private readonly Expression _newExpression; - private readonly ParameterExpression _oldParameter; + private readonly Expression _newExpression; + private readonly ParameterExpression _oldParameter; - private ParameterReplacerVisitor(ParameterExpression oldParameter, Expression newExpression) - { - _oldParameter = oldParameter; - _newExpression = newExpression; - } + private ParameterReplacerVisitor(ParameterExpression oldParameter, Expression newExpression) + { + _oldParameter = oldParameter; + _newExpression = newExpression; + } - internal static Expression Replace(Expression expression, ParameterExpression oldParameter, Expression newExpression) - => new ParameterReplacerVisitor(oldParameter, newExpression).Visit(expression); + internal static Expression Replace(Expression expression, ParameterExpression oldParameter, Expression newExpression) + => new ParameterReplacerVisitor(oldParameter, newExpression).Visit(expression); - protected override Expression VisitParameter(ParameterExpression p) - => p == _oldParameter ? _newExpression : p; + protected override Expression VisitParameter(ParameterExpression p) + => p == _oldParameter ? _newExpression : p; } diff --git a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Extensions/SearchExtension.cs b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Extensions/SearchExtension.cs index 381f5faf..dd199fc2 100644 --- a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Extensions/SearchExtension.cs +++ b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/Extensions/SearchExtension.cs @@ -7,53 +7,53 @@ namespace Ardalis.Specification.EntityFrameworkCore; public static class SearchExtension { - private static readonly MethodInfo _likeMethodInfo = typeof(DbFunctionsExtensions) - .GetMethod(nameof(DbFunctionsExtensions.Like), new Type[] { typeof(DbFunctions), typeof(string), typeof(string) }) - ?? throw new TargetException("The EF.Functions.Like not found"); - - private static readonly MemberExpression _functions = Expression.Property(null, typeof(EF).GetProperty(nameof(EF.Functions)) - ?? throw new TargetException("The EF.Functions not found!")); - - /// - /// Filters by applying an 'SQL LIKE' operation to it. - /// - /// The type being queried against. - /// The sequence of - /// - /// - /// Selector, the property to apply the SQL LIKE against. - /// SearchTerm, the value to use for the SQL LIKE. - /// - /// - /// - public static IQueryable Search(this IQueryable source, IEnumerable> criterias) - { - Expression? expr = null; - var parameter = Expression.Parameter(typeof(T), "x"); - - foreach (var criteria in criterias) + private static readonly MethodInfo _likeMethodInfo = typeof(DbFunctionsExtensions) + .GetMethod(nameof(DbFunctionsExtensions.Like), new Type[] { typeof(DbFunctions), typeof(string), typeof(string) }) + ?? throw new TargetException("The EF.Functions.Like not found"); + + private static readonly MemberExpression _functions = Expression.Property(null, typeof(EF).GetProperty(nameof(EF.Functions)) + ?? throw new TargetException("The EF.Functions not found!")); + + /// + /// Filters by applying an 'SQL LIKE' operation to it. + /// + /// The type being queried against. + /// The sequence of + /// + /// + /// Selector, the property to apply the SQL LIKE against. + /// SearchTerm, the value to use for the SQL LIKE. + /// + /// + /// + public static IQueryable Search(this IQueryable source, IEnumerable> criterias) { - if (string.IsNullOrEmpty(criteria.SearchTerm)) - continue; + Expression? expr = null; + var parameter = Expression.Parameter(typeof(T), "x"); - var propertySelector = ParameterReplacerVisitor.Replace(criteria.Selector, criteria.Selector.Parameters[0], parameter) as LambdaExpression; - _ = propertySelector ?? throw new InvalidExpressionException(); + foreach (var criteria in criterias) + { + if (string.IsNullOrEmpty(criteria.SearchTerm)) + continue; - // Create a closure - var searchTermAsExpression = ((Expression>)(() => criteria.SearchTerm)).Body; + var propertySelector = ParameterReplacerVisitor.Replace(criteria.Selector, criteria.Selector.Parameters[0], parameter) as LambdaExpression; + _ = propertySelector ?? throw new InvalidExpressionException(); - var likeExpression = Expression.Call( - null, - _likeMethodInfo, - _functions, - propertySelector.Body, - searchTermAsExpression); + // Create a closure + var searchTermAsExpression = ((Expression>)(() => criteria.SearchTerm)).Body; - expr = expr == null ? (Expression)likeExpression : Expression.OrElse(expr, likeExpression); - } + var likeExpression = Expression.Call( + null, + _likeMethodInfo, + _functions, + propertySelector.Body, + searchTermAsExpression); + + expr = expr == null ? (Expression)likeExpression : Expression.OrElse(expr, likeExpression); + } - return expr == null - ? source - : source.Where(Expression.Lambda>(expr, parameter)); - } + return expr == null + ? source + : source.Where(Expression.Lambda>(expr, parameter)); + } } diff --git a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/IRepositoryFactory.cs b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/IRepositoryFactory.cs index eaafd90d..62fc343e 100644 --- a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/IRepositoryFactory.cs +++ b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/IRepositoryFactory.cs @@ -9,9 +9,9 @@ /// public interface IRepositoryFactory { - /// - /// Generates a new repository instance - /// - /// The generated repository instance - public TRepository CreateRepository(); + /// + /// Generates a new repository instance + /// + /// The generated repository instance + public TRepository CreateRepository(); } diff --git a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/RepositoryBaseOfT.cs b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/RepositoryBaseOfT.cs index 1d94bda8..36ce58c9 100644 --- a/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/RepositoryBaseOfT.cs +++ b/Specification.EntityFrameworkCore/src/Ardalis.Specification.EntityFrameworkCore/RepositoryBaseOfT.cs @@ -5,198 +5,198 @@ namespace Ardalis.Specification.EntityFrameworkCore; /// public abstract class RepositoryBase : IRepositoryBase where T : class { - private readonly DbContext _dbContext; - private readonly ISpecificationEvaluator _specificationEvaluator; - - public RepositoryBase(DbContext dbContext) - : this(dbContext, SpecificationEvaluator.Default) - { - } - - /// - public RepositoryBase(DbContext dbContext, ISpecificationEvaluator specificationEvaluator) - { - _dbContext = dbContext; - _specificationEvaluator = specificationEvaluator; - } - - /// - public virtual async Task AddAsync(T entity, CancellationToken cancellationToken = default) - { - _dbContext.Set().Add(entity); - - await SaveChangesAsync(cancellationToken); - - return entity; - } - - /// - public virtual async Task> AddRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) - { - _dbContext.Set().AddRange(entities); - - await SaveChangesAsync(cancellationToken); - - return entities; - } - - /// - public virtual async Task UpdateAsync(T entity, CancellationToken cancellationToken = default) - { - _dbContext.Set().Update(entity); - - await SaveChangesAsync(cancellationToken); - } - - /// - public virtual async Task UpdateRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) - { - _dbContext.Set().UpdateRange(entities); - - await SaveChangesAsync(cancellationToken); - } - - /// - public virtual async Task DeleteAsync(T entity, CancellationToken cancellationToken = default) - { - _dbContext.Set().Remove(entity); - - await SaveChangesAsync(cancellationToken); - } - - /// - public virtual async Task DeleteRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) - { - _dbContext.Set().RemoveRange(entities); - - await SaveChangesAsync(cancellationToken); - } - - /// - public virtual async Task SaveChangesAsync(CancellationToken cancellationToken = default) - { - return await _dbContext.SaveChangesAsync(cancellationToken); - } - - /// - public virtual async Task GetByIdAsync(TId id, CancellationToken cancellationToken = default) where TId : notnull - { - return await _dbContext.Set().FindAsync(new object[] { id }, cancellationToken: cancellationToken); - } - - /// - [Obsolete] - public virtual async Task GetBySpecAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - return await ApplySpecification(specification).FirstOrDefaultAsync(cancellationToken); - } - - /// - [Obsolete] - public virtual async Task GetBySpecAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - return await ApplySpecification(specification).FirstOrDefaultAsync(cancellationToken); - } - - /// - public virtual async Task FirstOrDefaultAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - return await ApplySpecification(specification).FirstOrDefaultAsync(cancellationToken); - } - - /// - public virtual async Task FirstOrDefaultAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - return await ApplySpecification(specification).FirstOrDefaultAsync(cancellationToken); - } - - /// - public virtual async Task SingleOrDefaultAsync(ISingleResultSpecification specification, CancellationToken cancellationToken = default) - { - return await ApplySpecification(specification).SingleOrDefaultAsync(cancellationToken); - } - - /// - public virtual async Task SingleOrDefaultAsync(ISingleResultSpecification specification, CancellationToken cancellationToken = default) - { - return await ApplySpecification(specification).SingleOrDefaultAsync(cancellationToken); - } - - /// - public virtual async Task> ListAsync(CancellationToken cancellationToken = default) - { - return await _dbContext.Set().ToListAsync(cancellationToken); - } - - /// - public virtual async Task> ListAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - var queryResult = await ApplySpecification(specification).ToListAsync(cancellationToken); - - return specification.PostProcessingAction == null ? queryResult : specification.PostProcessingAction(queryResult).ToList(); - } - - /// - public virtual async Task> ListAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - var queryResult = await ApplySpecification(specification).ToListAsync(cancellationToken); - - return specification.PostProcessingAction == null ? queryResult : specification.PostProcessingAction(queryResult).ToList(); - } - - /// - public virtual async Task CountAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - return await ApplySpecification(specification, true).CountAsync(cancellationToken); - } - - /// - public virtual async Task CountAsync(CancellationToken cancellationToken = default) - { - return await _dbContext.Set().CountAsync(cancellationToken); - } - - /// - public virtual async Task AnyAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - return await ApplySpecification(specification, true).AnyAsync(cancellationToken); - } - - /// - public virtual async Task AnyAsync(CancellationToken cancellationToken = default) - { - return await _dbContext.Set().AnyAsync(cancellationToken); - } - - /// - public virtual IAsyncEnumerable AsAsyncEnumerable(ISpecification specification) - { - return ApplySpecification(specification).AsAsyncEnumerable(); - } - - /// - /// Filters the entities of , to those that match the encapsulated query logic of the - /// . - /// - /// The encapsulated query logic. - /// The filtered entities as an . - protected virtual IQueryable ApplySpecification(ISpecification specification, bool evaluateCriteriaOnly = false) - { - return _specificationEvaluator.GetQuery(_dbContext.Set().AsQueryable(), specification, evaluateCriteriaOnly); - } - - /// - /// Filters all entities of , that matches the encapsulated query logic of the - /// , from the database. - /// - /// Projects each entity into a new form, being . - /// - /// - /// The type of the value returned by the projection. - /// The encapsulated query logic. - /// The filtered projected entities as an . - protected virtual IQueryable ApplySpecification(ISpecification specification) - { - return _specificationEvaluator.GetQuery(_dbContext.Set().AsQueryable(), specification); - } + private readonly DbContext _dbContext; + private readonly ISpecificationEvaluator _specificationEvaluator; + + public RepositoryBase(DbContext dbContext) + : this(dbContext, SpecificationEvaluator.Default) + { + } + + /// + public RepositoryBase(DbContext dbContext, ISpecificationEvaluator specificationEvaluator) + { + _dbContext = dbContext; + _specificationEvaluator = specificationEvaluator; + } + + /// + public virtual async Task AddAsync(T entity, CancellationToken cancellationToken = default) + { + _dbContext.Set().Add(entity); + + await SaveChangesAsync(cancellationToken); + + return entity; + } + + /// + public virtual async Task> AddRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) + { + _dbContext.Set().AddRange(entities); + + await SaveChangesAsync(cancellationToken); + + return entities; + } + + /// + public virtual async Task UpdateAsync(T entity, CancellationToken cancellationToken = default) + { + _dbContext.Set().Update(entity); + + await SaveChangesAsync(cancellationToken); + } + + /// + public virtual async Task UpdateRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) + { + _dbContext.Set().UpdateRange(entities); + + await SaveChangesAsync(cancellationToken); + } + + /// + public virtual async Task DeleteAsync(T entity, CancellationToken cancellationToken = default) + { + _dbContext.Set().Remove(entity); + + await SaveChangesAsync(cancellationToken); + } + + /// + public virtual async Task DeleteRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) + { + _dbContext.Set().RemoveRange(entities); + + await SaveChangesAsync(cancellationToken); + } + + /// + public virtual async Task SaveChangesAsync(CancellationToken cancellationToken = default) + { + return await _dbContext.SaveChangesAsync(cancellationToken); + } + + /// + public virtual async Task GetByIdAsync(TId id, CancellationToken cancellationToken = default) where TId : notnull + { + return await _dbContext.Set().FindAsync(new object[] { id }, cancellationToken: cancellationToken); + } + + /// + [Obsolete] + public virtual async Task GetBySpecAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + return await ApplySpecification(specification).FirstOrDefaultAsync(cancellationToken); + } + + /// + [Obsolete] + public virtual async Task GetBySpecAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + return await ApplySpecification(specification).FirstOrDefaultAsync(cancellationToken); + } + + /// + public virtual async Task FirstOrDefaultAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + return await ApplySpecification(specification).FirstOrDefaultAsync(cancellationToken); + } + + /// + public virtual async Task FirstOrDefaultAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + return await ApplySpecification(specification).FirstOrDefaultAsync(cancellationToken); + } + + /// + public virtual async Task SingleOrDefaultAsync(ISingleResultSpecification specification, CancellationToken cancellationToken = default) + { + return await ApplySpecification(specification).SingleOrDefaultAsync(cancellationToken); + } + + /// + public virtual async Task SingleOrDefaultAsync(ISingleResultSpecification specification, CancellationToken cancellationToken = default) + { + return await ApplySpecification(specification).SingleOrDefaultAsync(cancellationToken); + } + + /// + public virtual async Task> ListAsync(CancellationToken cancellationToken = default) + { + return await _dbContext.Set().ToListAsync(cancellationToken); + } + + /// + public virtual async Task> ListAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + var queryResult = await ApplySpecification(specification).ToListAsync(cancellationToken); + + return specification.PostProcessingAction == null ? queryResult : specification.PostProcessingAction(queryResult).ToList(); + } + + /// + public virtual async Task> ListAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + var queryResult = await ApplySpecification(specification).ToListAsync(cancellationToken); + + return specification.PostProcessingAction == null ? queryResult : specification.PostProcessingAction(queryResult).ToList(); + } + + /// + public virtual async Task CountAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + return await ApplySpecification(specification, true).CountAsync(cancellationToken); + } + + /// + public virtual async Task CountAsync(CancellationToken cancellationToken = default) + { + return await _dbContext.Set().CountAsync(cancellationToken); + } + + /// + public virtual async Task AnyAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + return await ApplySpecification(specification, true).AnyAsync(cancellationToken); + } + + /// + public virtual async Task AnyAsync(CancellationToken cancellationToken = default) + { + return await _dbContext.Set().AnyAsync(cancellationToken); + } + + /// + public virtual IAsyncEnumerable AsAsyncEnumerable(ISpecification specification) + { + return ApplySpecification(specification).AsAsyncEnumerable(); + } + + /// + /// Filters the entities of , to those that match the encapsulated query logic of the + /// . + /// + /// The encapsulated query logic. + /// The filtered entities as an . + protected virtual IQueryable ApplySpecification(ISpecification specification, bool evaluateCriteriaOnly = false) + { + return _specificationEvaluator.GetQuery(_dbContext.Set().AsQueryable(), specification, evaluateCriteriaOnly); + } + + /// + /// Filters all entities of , that matches the encapsulated query logic of the + /// , from the database. + /// + /// Projects each entity into a new form, being . + /// + /// + /// The type of the value returned by the projection. + /// The encapsulated query logic. + /// The filtered projected entities as an . + protected virtual IQueryable ApplySpecification(ISpecification specification) + { + return _specificationEvaluator.GetQuery(_dbContext.Set().AsQueryable(), specification); + } } diff --git a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/ContextFactoryRepositoryBaseOfTTests.cs b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/ContextFactoryRepositoryBaseOfTTests.cs index b49110ef..7ed719c5 100644 --- a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/ContextFactoryRepositoryBaseOfTTests.cs +++ b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/ContextFactoryRepositoryBaseOfTTests.cs @@ -8,139 +8,139 @@ namespace Ardalis.Specification.EntityFrameworkCore.IntegrationTests; public class ContextFactoryRepositoryBaseOfTTests : IClassFixture { - protected TestDbContext dbContext; - protected IServiceProvider serviceProvider; - protected ContextFactoryRepository repository; + protected TestDbContext dbContext; + protected IServiceProvider serviceProvider; + protected ContextFactoryRepository repository; - public ContextFactoryRepositoryBaseOfTTests(SharedDatabaseFixture fixture) - { - dbContext = fixture.CreateContext(); + public ContextFactoryRepositoryBaseOfTTests(SharedDatabaseFixture fixture) + { + dbContext = fixture.CreateContext(); - serviceProvider = new ServiceCollection() - .AddDbContextFactory((builder => builder.UseSqlServer(fixture.Connection)), - ServiceLifetime.Transient).BuildServiceProvider(); + serviceProvider = new ServiceCollection() + .AddDbContextFactory((builder => builder.UseSqlServer(fixture.Connection)), + ServiceLifetime.Transient).BuildServiceProvider(); - var contextFactory = serviceProvider.GetService>(); - repository = new ContextFactoryRepository(contextFactory); - } + var contextFactory = serviceProvider.GetService>(); + repository = new ContextFactoryRepository(contextFactory); + } - [Fact] - public async Task Saves_new_entity() - { - var country = await dbContext.Countries.FirstOrDefaultAsync(); + [Fact] + public async Task Saves_new_entity() + { + var country = await dbContext.Countries.FirstOrDefaultAsync(); - var company = new Company(); - company.Name = "Test save new company name"; - company.CountryId = country.Id; + var company = new Company(); + company.Name = "Test save new company name"; + company.CountryId = country.Id; - await repository.AddAsync(company); - Assert.NotEqual(0, company.Id); - } + await repository.AddAsync(company); + Assert.NotEqual(0, company.Id); + } - [Fact] - public async Task Updates_existing_entity() - { - var country = await dbContext.Countries.FirstOrDefaultAsync(); + [Fact] + public async Task Updates_existing_entity() + { + var country = await dbContext.Countries.FirstOrDefaultAsync(); - var company = new Company { Name = "Test update existing company name", CountryId = country.Id }; - await repository.AddAsync(company); + var company = new Company { Name = "Test update existing company name", CountryId = country.Id }; + await repository.AddAsync(company); - var existingCompany = await repository.GetByIdAsync(company.Id); - existingCompany.Name = "Updated company name"; - await repository.UpdateAsync(existingCompany); + var existingCompany = await repository.GetByIdAsync(company.Id); + existingCompany.Name = "Updated company name"; + await repository.UpdateAsync(existingCompany); - var validationCompany = await dbContext.Companies.FirstOrDefaultAsync(x => x.Id == company.Id); - Assert.Equal(validationCompany.Name, existingCompany.Name); - } + var validationCompany = await dbContext.Companies.FirstOrDefaultAsync(x => x.Id == company.Id); + Assert.Equal(validationCompany.Name, existingCompany.Name); + } - [Fact] - public async Task Updates_existing_entity_across_context_instances() - { - var contextFactory = serviceProvider.GetService>(); - var companyRetrievalRepository = new ContextFactoryRepository(contextFactory); - var companySaveRepository = new ContextFactoryRepository(contextFactory); + [Fact] + public async Task Updates_existing_entity_across_context_instances() + { + var contextFactory = serviceProvider.GetService>(); + var companyRetrievalRepository = new ContextFactoryRepository(contextFactory); + var companySaveRepository = new ContextFactoryRepository(contextFactory); - var country = await dbContext.Countries.FirstOrDefaultAsync(); + var country = await dbContext.Countries.FirstOrDefaultAsync(); - var company = new Company { Name = "Test update existing company name", CountryId = country.Id }; - await repository.AddAsync(company); + var company = new Company { Name = "Test update existing company name", CountryId = country.Id }; + await repository.AddAsync(company); - var existingCompany = await companyRetrievalRepository.GetByIdAsync(company.Id); - existingCompany.Name = "Updated company name"; - await companySaveRepository.UpdateAsync(existingCompany); + var existingCompany = await companyRetrievalRepository.GetByIdAsync(company.Id); + existingCompany.Name = "Updated company name"; + await companySaveRepository.UpdateAsync(existingCompany); - var validationCompany = await dbContext.Companies.FirstOrDefaultAsync(x => x.Id == company.Id); - Assert.Equal(validationCompany.Name, existingCompany.Name); - } + var validationCompany = await dbContext.Companies.FirstOrDefaultAsync(x => x.Id == company.Id); + Assert.Equal(validationCompany.Name, existingCompany.Name); + } - [Fact] - public async Task Updates_graph() - { - var country = await dbContext.Countries.FirstOrDefaultAsync(); + [Fact] + public async Task Updates_graph() + { + var country = await dbContext.Countries.FirstOrDefaultAsync(); - var company = new Company { Name = "Test update graph", CountryId = country.Id }; - var store = new Store { Name = "Store Number 1" }; - company.Stores.Add(store); + var company = new Company { Name = "Test update graph", CountryId = country.Id }; + var store = new Store { Name = "Store Number 1" }; + company.Stores.Add(store); - await repository.AddAsync(company); + await repository.AddAsync(company); - var spec = new GetCompanyWithStoresSpec(company.Id); - var existingCompany = await repository.FirstOrDefaultAsync(spec); - existingCompany.Name = "Updated company name"; - var existingStore = existingCompany.Stores.FirstOrDefault(); - existingStore.Name = "Updated Store Name"; + var spec = new GetCompanyWithStoresSpec(company.Id); + var existingCompany = await repository.FirstOrDefaultAsync(spec); + existingCompany.Name = "Updated company name"; + var existingStore = existingCompany.Stores.FirstOrDefault(); + existingStore.Name = "Updated Store Name"; - await repository.UpdateAsync(existingCompany); + await repository.UpdateAsync(existingCompany); - var validationCompany = await dbContext.Companies.FirstOrDefaultAsync(x => x.Id == company.Id); - Assert.Equal(validationCompany.Name, existingCompany.Name); + var validationCompany = await dbContext.Companies.FirstOrDefaultAsync(x => x.Id == company.Id); + Assert.Equal(validationCompany.Name, existingCompany.Name); - var validationStore = await dbContext.Stores.FirstOrDefaultAsync(x => x.CompanyId == company.Id); - Assert.Equal(validationStore.Name, existingStore.Name); - } + var validationStore = await dbContext.Stores.FirstOrDefaultAsync(x => x.CompanyId == company.Id); + Assert.Equal(validationStore.Name, existingStore.Name); + } - [Fact] - public async Task Updates_graph_across_context_instances() - { - var contextFactory = serviceProvider.GetService>(); - var companyRetrievalRepository = new ContextFactoryRepository(contextFactory); - var companySaveRepository = new ContextFactoryRepository(contextFactory); + [Fact] + public async Task Updates_graph_across_context_instances() + { + var contextFactory = serviceProvider.GetService>(); + var companyRetrievalRepository = new ContextFactoryRepository(contextFactory); + var companySaveRepository = new ContextFactoryRepository(contextFactory); - var country = await dbContext.Countries.FirstOrDefaultAsync(); + var country = await dbContext.Countries.FirstOrDefaultAsync(); - var company = new Company { Name = "Test update graph", CountryId = country.Id }; - var store = new Store { Name = "Store Number 1" }; - company.Stores.Add(store); + var company = new Company { Name = "Test update graph", CountryId = country.Id }; + var store = new Store { Name = "Store Number 1" }; + company.Stores.Add(store); - await repository.AddAsync(company); + await repository.AddAsync(company); - var spec = new GetCompanyWithStoresSpec(company.Id); - var existingCompany = await companyRetrievalRepository.FirstOrDefaultAsync(spec); - existingCompany.Name = "Updated company name"; - var existingStore = existingCompany.Stores.FirstOrDefault(); - existingStore.Name = "Updated Store Name"; + var spec = new GetCompanyWithStoresSpec(company.Id); + var existingCompany = await companyRetrievalRepository.FirstOrDefaultAsync(spec); + existingCompany.Name = "Updated company name"; + var existingStore = existingCompany.Stores.FirstOrDefault(); + existingStore.Name = "Updated Store Name"; - await companySaveRepository.UpdateAsync(existingCompany); + await companySaveRepository.UpdateAsync(existingCompany); - var validationCompany = await dbContext.Companies.FirstOrDefaultAsync(x => x.Id == company.Id); - Assert.Equal(validationCompany.Name, existingCompany.Name); + var validationCompany = await dbContext.Companies.FirstOrDefaultAsync(x => x.Id == company.Id); + Assert.Equal(validationCompany.Name, existingCompany.Name); - var validationStore = await dbContext.Stores.FirstOrDefaultAsync(x => x.CompanyId == company.Id); - Assert.Equal(validationStore.Name, existingStore.Name); - } + var validationStore = await dbContext.Stores.FirstOrDefaultAsync(x => x.CompanyId == company.Id); + Assert.Equal(validationStore.Name, existingStore.Name); + } - [Fact] - public async Task Deletes_entity() - { - var country = await dbContext.Countries.FirstOrDefaultAsync(); + [Fact] + public async Task Deletes_entity() + { + var country = await dbContext.Countries.FirstOrDefaultAsync(); - var company = new Company { Name = "Test update graph", CountryId = country.Id }; - await repository.AddAsync(company); + var company = new Company { Name = "Test update graph", CountryId = country.Id }; + await repository.AddAsync(company); - var companyId = company.Id; - await repository.DeleteAsync(company); + var companyId = company.Id; + await repository.DeleteAsync(company); - var validationCompany = await repository.GetByIdAsync(companyId); - Assert.Null(validationCompany); - } + var validationCompany = await repository.GetByIdAsync(companyId); + Assert.Null(validationCompany); + } } diff --git a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/EFRepositoryFactoryTests.cs b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/EFRepositoryFactoryTests.cs index 659da398..18d66fac 100644 --- a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/EFRepositoryFactoryTests.cs +++ b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/EFRepositoryFactoryTests.cs @@ -9,117 +9,117 @@ namespace Ardalis.Specification.EntityFrameworkCore.IntegrationTests; public class EFRepositoryFactoryTests : IClassFixture { - protected TestDbContext dbContext; - protected IServiceProvider serviceProvider; - protected IRepositoryFactory> repositoryFactory; - protected IDbContextFactory contextFactory; - - public EFRepositoryFactoryTests(SharedDatabaseFixture fixture) - { - dbContext = fixture.CreateContext(); - - serviceProvider = new ServiceCollection() - .AddDbContextFactory((builder => builder.UseSqlServer(fixture.Connection)), - ServiceLifetime.Transient).BuildServiceProvider(); - - contextFactory = serviceProvider.GetService>(); - repositoryFactory = - new EFRepositoryFactory, Repository, TestDbContext>(contextFactory); - } - - [Fact] - public void CorrectlyInstantiatesRepository() - { - var mockContextFactory = new Mock>(); - mockContextFactory.Setup(x => x.CreateDbContext()) - .Returns(() => new SampleDbContext(new DbContextOptions())); - - var repositoryFactory = - new EFRepositoryFactory, MyRepository, SampleDbContext>(mockContextFactory - .Object); - - var repository = repositoryFactory.CreateRepository(); - Assert.IsType>(repository); - } - - [Fact] - public async Task Saves_new_entity() - { - var repository = repositoryFactory.CreateRepository(); - var country = await dbContext.Countries.FirstOrDefaultAsync(); - - var company = new Company(); - company.Name = "Test save new company name"; - company.CountryId = country.Id; - - await repository.AddAsync(company); - Assert.NotEqual(0, company.Id); - } - - [Fact] - public async Task Updates_existing_entity() - { - var repository = repositoryFactory.CreateRepository(); - var country = await dbContext.Countries.FirstOrDefaultAsync(); - - var company = new Company { Name = "Test update existing company name", CountryId = country.Id }; - await repository.AddAsync(company); - - var existingCompany = await repository.GetByIdAsync(company.Id); - existingCompany.Name = "Updated company name"; - await repository.UpdateAsync(existingCompany); - - var validationCompany = await dbContext.Companies.FirstOrDefaultAsync(x => x.Id == company.Id); - Assert.Equal(validationCompany.Name, existingCompany.Name); - } - - [Fact] - public async Task Updates_graph() - { - var repository = repositoryFactory.CreateRepository(); - var country = await dbContext.Countries.FirstOrDefaultAsync(); - - var company = new Company { Name = "Test update graph", CountryId = country.Id }; - var store = new Store { Name = "Store Number 1" }; - company.Stores.Add(store); - - await repository.AddAsync(company); - - var spec = new GetCompanyWithStoresSpec(company.Id); - var existingCompany = await repository.FirstOrDefaultAsync(spec); - existingCompany.Name = "Updated company name"; - var existingStore = existingCompany.Stores.FirstOrDefault(); - existingStore.Name = "Updated Store Name"; - - await repository.UpdateAsync(existingCompany); - - var validationCompany = await dbContext.Companies.FirstOrDefaultAsync(x => x.Id == company.Id); - Assert.Equal(validationCompany.Name, existingCompany.Name); - - var validationStore = await dbContext.Stores.FirstOrDefaultAsync(x => x.CompanyId == company.Id); - Assert.Equal(validationStore.Name, existingStore.Name); - } - - public record Customer(int Id, string Name); - - public class SampleDbContext : DbContext - { - public DbSet Customers { get; set; } - - public SampleDbContext(DbContextOptions options) - : base(options) + protected TestDbContext dbContext; + protected IServiceProvider serviceProvider; + protected IRepositoryFactory> repositoryFactory; + protected IDbContextFactory contextFactory; + + public EFRepositoryFactoryTests(SharedDatabaseFixture fixture) + { + dbContext = fixture.CreateContext(); + + serviceProvider = new ServiceCollection() + .AddDbContextFactory((builder => builder.UseSqlServer(fixture.Connection)), + ServiceLifetime.Transient).BuildServiceProvider(); + + contextFactory = serviceProvider.GetService>(); + repositoryFactory = + new EFRepositoryFactory, Repository, TestDbContext>(contextFactory); + } + + [Fact] + public void CorrectlyInstantiatesRepository() + { + var mockContextFactory = new Mock>(); + mockContextFactory.Setup(x => x.CreateDbContext()) + .Returns(() => new SampleDbContext(new DbContextOptions())); + + var repositoryFactory = + new EFRepositoryFactory, MyRepository, SampleDbContext>(mockContextFactory + .Object); + + var repository = repositoryFactory.CreateRepository(); + Assert.IsType>(repository); + } + + [Fact] + public async Task Saves_new_entity() { + var repository = repositoryFactory.CreateRepository(); + var country = await dbContext.Countries.FirstOrDefaultAsync(); + + var company = new Company(); + company.Name = "Test save new company name"; + company.CountryId = country.Id; + + await repository.AddAsync(company); + Assert.NotEqual(0, company.Id); } - } - public interface IRepository : IRepositoryBase where T : class - { - } + [Fact] + public async Task Updates_existing_entity() + { + var repository = repositoryFactory.CreateRepository(); + var country = await dbContext.Countries.FirstOrDefaultAsync(); + + var company = new Company { Name = "Test update existing company name", CountryId = country.Id }; + await repository.AddAsync(company); + + var existingCompany = await repository.GetByIdAsync(company.Id); + existingCompany.Name = "Updated company name"; + await repository.UpdateAsync(existingCompany); + + var validationCompany = await dbContext.Companies.FirstOrDefaultAsync(x => x.Id == company.Id); + Assert.Equal(validationCompany.Name, existingCompany.Name); + } + + [Fact] + public async Task Updates_graph() + { + var repository = repositoryFactory.CreateRepository(); + var country = await dbContext.Countries.FirstOrDefaultAsync(); + + var company = new Company { Name = "Test update graph", CountryId = country.Id }; + var store = new Store { Name = "Store Number 1" }; + company.Stores.Add(store); + + await repository.AddAsync(company); + + var spec = new GetCompanyWithStoresSpec(company.Id); + var existingCompany = await repository.FirstOrDefaultAsync(spec); + existingCompany.Name = "Updated company name"; + var existingStore = existingCompany.Stores.FirstOrDefault(); + existingStore.Name = "Updated Store Name"; + + await repository.UpdateAsync(existingCompany); + + var validationCompany = await dbContext.Companies.FirstOrDefaultAsync(x => x.Id == company.Id); + Assert.Equal(validationCompany.Name, existingCompany.Name); + + var validationStore = await dbContext.Stores.FirstOrDefaultAsync(x => x.CompanyId == company.Id); + Assert.Equal(validationStore.Name, existingStore.Name); + } + + public record Customer(int Id, string Name); + + public class SampleDbContext : DbContext + { + public DbSet Customers { get; set; } + + public SampleDbContext(DbContextOptions options) + : base(options) + { + } + } + + public interface IRepository : IRepositoryBase where T : class + { + } - public class MyRepository : RepositoryBase, IRepository where T : class - { - public MyRepository(SampleDbContext dbContext) : base(dbContext) + public class MyRepository : RepositoryBase, IRepository where T : class { + public MyRepository(SampleDbContext dbContext) : base(dbContext) + { + } } - } } diff --git a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/ContextFactoryRepositoryOfT.cs b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/ContextFactoryRepositoryOfT.cs index 5df09fad..adc3cfee 100644 --- a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/ContextFactoryRepositoryOfT.cs +++ b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/ContextFactoryRepositoryOfT.cs @@ -5,12 +5,12 @@ namespace Ardalis.Specification.EntityFrameworkCore.IntegrationTests.Fixture; public class ContextFactoryRepository : ContextFactoryRepositoryBaseOfT where T : class where TContext : DbContext { - public ContextFactoryRepository(IDbContextFactory dbContextFactory) : base(dbContextFactory) - { - } + public ContextFactoryRepository(IDbContextFactory dbContextFactory) : base(dbContextFactory) + { + } - public ContextFactoryRepository(IDbContextFactory dbContextFactory, - ISpecificationEvaluator specificationEvaluator) : base(dbContextFactory, specificationEvaluator) - { - } + public ContextFactoryRepository(IDbContextFactory dbContextFactory, + ISpecificationEvaluator specificationEvaluator) : base(dbContextFactory, specificationEvaluator) + { + } } diff --git a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/GetCompanyWithStoresSpec.cs b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/GetCompanyWithStoresSpec.cs index 02283a81..34ae57c6 100644 --- a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/GetCompanyWithStoresSpec.cs +++ b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/GetCompanyWithStoresSpec.cs @@ -4,8 +4,8 @@ namespace Ardalis.Specification.EntityFrameworkCore.IntegrationTests.Fixture; public class GetCompanyWithStoresSpec : Specification, ISingleResultSpecification { - public GetCompanyWithStoresSpec(int companyId) - { - Query.Where(x => x.Id == companyId).Include(x => x.Stores); - } + public GetCompanyWithStoresSpec(int companyId) + { + Query.Where(x => x.Id == companyId).Include(x => x.Stores); + } } diff --git a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/IntegrationTestBase.cs b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/IntegrationTestBase.cs index 5823519a..ff6e6f7f 100644 --- a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/IntegrationTestBase.cs +++ b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/IntegrationTestBase.cs @@ -5,15 +5,15 @@ namespace Ardalis.Specification.EntityFrameworkCore.IntegrationTests.Fixture; public abstract class IntegrationTestBase : IClassFixture { - protected TestDbContext dbContext; - protected Repository companyRepository; - protected Repository storeRepository; + protected TestDbContext dbContext; + protected Repository companyRepository; + protected Repository storeRepository; - protected IntegrationTestBase(SharedDatabaseFixture fixture, ISpecificationEvaluator specificationEvaluator) - { - dbContext = fixture.CreateContext(); + protected IntegrationTestBase(SharedDatabaseFixture fixture, ISpecificationEvaluator specificationEvaluator) + { + dbContext = fixture.CreateContext(); - companyRepository = new Repository(dbContext, specificationEvaluator); - storeRepository = new Repository(dbContext, specificationEvaluator); - } + companyRepository = new Repository(dbContext, specificationEvaluator); + storeRepository = new Repository(dbContext, specificationEvaluator); + } } diff --git a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/LoggerFactoryProvider.cs b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/LoggerFactoryProvider.cs index 848a14fe..addb289a 100644 --- a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/LoggerFactoryProvider.cs +++ b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/LoggerFactoryProvider.cs @@ -4,9 +4,9 @@ namespace Ardalis.Specification.EntityFrameworkCore.IntegrationTests.Fixture; public class LoggerFactoryProvider { - public static readonly ILoggerFactory LoggerFactoryInstance = Microsoft.Extensions.Logging.LoggerFactory.Create(builder => - { - builder.AddFilter("Ardalis.Specification.EF", LogLevel.Debug); - builder.AddConsole(); - }); + public static readonly ILoggerFactory LoggerFactoryInstance = Microsoft.Extensions.Logging.LoggerFactory.Create(builder => + { + builder.AddFilter("Ardalis.Specification.EF", LogLevel.Debug); + builder.AddConsole(); + }); } diff --git a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/RepositoryOfT.cs b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/RepositoryOfT.cs index 74a3ed6d..4d000e94 100644 --- a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/RepositoryOfT.cs +++ b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/RepositoryOfT.cs @@ -3,14 +3,14 @@ /// public class Repository : RepositoryBase where T : class { - protected readonly TestDbContext dbContext; + protected readonly TestDbContext dbContext; - public Repository(TestDbContext dbContext) : this(dbContext, SpecificationEvaluator.Default) - { - } + public Repository(TestDbContext dbContext) : this(dbContext, SpecificationEvaluator.Default) + { + } - public Repository(TestDbContext dbContext, ISpecificationEvaluator specificationEvaluator) : base(dbContext, specificationEvaluator) - { - this.dbContext = dbContext; - } + public Repository(TestDbContext dbContext, ISpecificationEvaluator specificationEvaluator) : base(dbContext, specificationEvaluator) + { + this.dbContext = dbContext; + } } diff --git a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/SharedDatabaseFixture.cs b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/SharedDatabaseFixture.cs index 7fdf88d9..de338a3b 100644 --- a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/SharedDatabaseFixture.cs +++ b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/SharedDatabaseFixture.cs @@ -7,81 +7,81 @@ namespace Ardalis.Specification.EntityFrameworkCore.IntegrationTests.Fixture; public class SharedDatabaseFixture : IDisposable { - public const string _connectionStringDocker = "Data Source=databaseEFCore;Initial Catalog=SpecificationEFCoreTestsDB;PersistSecurityInfo=True;User ID=sa;Password=P@ssW0rd!;TrustServerCertificate=Yes"; - public const string _connectionStringLocalDb = "Server=(localdb)\\mssqllocaldb;Integrated Security=SSPI;Initial Catalog=SpecificationEFTestsDB;ConnectRetryCount=0"; + public const string _connectionStringDocker = "Data Source=databaseEFCore;Initial Catalog=SpecificationEFCoreTestsDB;PersistSecurityInfo=True;User ID=sa;Password=P@ssW0rd!;TrustServerCertificate=Yes"; + public const string _connectionStringLocalDb = "Server=(localdb)\\mssqllocaldb;Integrated Security=SSPI;Initial Catalog=SpecificationEFTestsDB;ConnectRetryCount=0"; - private static readonly object _lock = new(); - private static bool _databaseInitialized; + private static readonly object _lock = new(); + private static bool _databaseInitialized; - public SharedDatabaseFixture() - { - var isLocalDBInstalled = false; - - using (var localDB = new SqlLocalDbApi()) + public SharedDatabaseFixture() { - isLocalDBInstalled = localDB.IsLocalDBInstalled(); - } - - Connection = isLocalDBInstalled - ? new SqlConnection(_connectionStringLocalDb) - : new SqlConnection(_connectionStringDocker); + var isLocalDBInstalled = false; - Seed(); + using (var localDB = new SqlLocalDbApi()) + { + isLocalDBInstalled = localDB.IsLocalDBInstalled(); + } - Connection.Open(); - } + Connection = isLocalDBInstalled + ? new SqlConnection(_connectionStringLocalDb) + : new SqlConnection(_connectionStringDocker); - // This would work only if the DB already exists, otherwise obviously won't be able to open a connection. - // Therefore, in the ctor we're using a Nuget package for this check, it's more robust. - private static bool IsLocalDbAvailable1() - { - try - { - using (var connection = new SqlConnection(_connectionStringLocalDb)) - { - connection.Open(); - connection.Close(); - } + Seed(); - return true; + Connection.Open(); } - catch (Exception) + + // This would work only if the DB already exists, otherwise obviously won't be able to open a connection. + // Therefore, in the ctor we're using a Nuget package for this check, it's more robust. + private static bool IsLocalDbAvailable1() { - return false; - } - } + try + { + using (var connection = new SqlConnection(_connectionStringLocalDb)) + { + connection.Open(); + connection.Close(); + } - public DbConnection Connection { get; } + return true; + } + catch (Exception) + { + return false; + } + } - public TestDbContext CreateContext(DbTransaction transaction = null) - { - var context = new TestDbContext(new DbContextOptionsBuilder().UseSqlServer(Connection).Options); + public DbConnection Connection { get; } - if (transaction != null) + public TestDbContext CreateContext(DbTransaction transaction = null) { - context.Database.UseTransaction(transaction); - } + var context = new TestDbContext(new DbContextOptionsBuilder().UseSqlServer(Connection).Options); - return context; - } + if (transaction != null) + { + context.Database.UseTransaction(transaction); + } + + return context; + } - private void Seed() - { - lock (_lock) + private void Seed() { - if (!_databaseInitialized) - { - using (var context = CreateContext()) + lock (_lock) { - context.Database.EnsureDeleted(); - context.Database.EnsureCreated(); + if (!_databaseInitialized) + { + using (var context = CreateContext()) + { + context.Database.EnsureDeleted(); + context.Database.EnsureCreated(); + } + + _databaseInitialized = true; + } } - - _databaseInitialized = true; - } } - } - public void Dispose() => Connection.Dispose(); + public void Dispose() => Connection.Dispose(); } diff --git a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/TestDbContext.cs b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/TestDbContext.cs index 8638913f..864b3e98 100644 --- a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/TestDbContext.cs +++ b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/Fixture/TestDbContext.cs @@ -6,32 +6,32 @@ namespace Ardalis.Specification.EntityFrameworkCore.IntegrationTests.Fixture; public class TestDbContext : DbContext { - public DbSet Countries => Set(); - public DbSet Companies => Set(); - public DbSet Stores => Set(); - public DbSet
Addresses => Set
(); - public DbSet Products => Set(); + public DbSet Countries => Set(); + public DbSet Companies => Set(); + public DbSet Stores => Set(); + public DbSet
Addresses => Set
(); + public DbSet Products => Set(); - public TestDbContext(DbContextOptions options) : base(options) - { - } + public TestDbContext(DbContextOptions options) : base(options) + { + } - protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - { - optionsBuilder.UseLoggerFactory(LoggerFactoryProvider.LoggerFactoryInstance); - base.OnConfiguring(optionsBuilder); - } + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + optionsBuilder.UseLoggerFactory(LoggerFactoryProvider.LoggerFactoryInstance); + base.OnConfiguring(optionsBuilder); + } - protected override void OnModelCreating(ModelBuilder modelBuilder) - { - base.OnModelCreating(modelBuilder); + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); - modelBuilder.Entity().HasOne(x => x.Address).WithOne(x => x!.Store!).HasForeignKey
(x => x.StoreId); + modelBuilder.Entity().HasOne(x => x.Address).WithOne(x => x!.Store!).HasForeignKey
(x => x.StoreId); - modelBuilder.Entity().HasData(CountrySeed.Get()); - modelBuilder.Entity().HasData(CompanySeed.Get()); - modelBuilder.Entity
().HasData(AddressSeed.Get()); - modelBuilder.Entity().HasData(StoreSeed.Get()); - modelBuilder.Entity().HasData(ProductSeed.Get()); - } + modelBuilder.Entity().HasData(CountrySeed.Get()); + modelBuilder.Entity().HasData(CompanySeed.Get()); + modelBuilder.Entity
().HasData(AddressSeed.Get()); + modelBuilder.Entity().HasData(StoreSeed.Get()); + modelBuilder.Entity().HasData(ProductSeed.Get()); + } } diff --git a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/RepositoryOfT_AnyAsync.cs b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/RepositoryOfT_AnyAsync.cs index 02225c65..c0193fc7 100644 --- a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/RepositoryOfT_AnyAsync.cs +++ b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/RepositoryOfT_AnyAsync.cs @@ -8,43 +8,43 @@ namespace Ardalis.Specification.EntityFrameworkCore.IntegrationTests; public class RepositoryOfT_AnyAsync : RepositoryOfT_AnyAsync_TestKit { - public RepositoryOfT_AnyAsync(SharedDatabaseFixture fixture) : base(fixture, SpecificationEvaluator.Default) - { - } + public RepositoryOfT_AnyAsync(SharedDatabaseFixture fixture) : base(fixture, SpecificationEvaluator.Default) + { + } } public class RepositoryOfT_AnyAsync_Cached : RepositoryOfT_AnyAsync_TestKit { - public RepositoryOfT_AnyAsync_Cached(SharedDatabaseFixture fixture) : base(fixture, SpecificationEvaluator.Cached) - { - } + public RepositoryOfT_AnyAsync_Cached(SharedDatabaseFixture fixture) : base(fixture, SpecificationEvaluator.Cached) + { + } } public abstract class RepositoryOfT_AnyAsync_TestKit : IntegrationTestBase { - protected RepositoryOfT_AnyAsync_TestKit(SharedDatabaseFixture fixture, ISpecificationEvaluator specificationEvaluator) : base(fixture, specificationEvaluator) { } + protected RepositoryOfT_AnyAsync_TestKit(SharedDatabaseFixture fixture, ISpecificationEvaluator specificationEvaluator) : base(fixture, specificationEvaluator) { } - [Fact] - public virtual async Task ReturnsTrueOnStoresRecords_WithoutSpec() - { - var result = await storeRepository.AnyAsync(); + [Fact] + public virtual async Task ReturnsTrueOnStoresRecords_WithoutSpec() + { + var result = await storeRepository.AnyAsync(); - result.Should().BeTrue(); - } + result.Should().BeTrue(); + } - [Fact] - public virtual async Task ReturnsTrue_GivenStoreByIdSpecWithValidStore() - { - var result = await storeRepository.AnyAsync(new StoreByIdSpec(StoreSeed.VALID_STORE_ID)); + [Fact] + public virtual async Task ReturnsTrue_GivenStoreByIdSpecWithValidStore() + { + var result = await storeRepository.AnyAsync(new StoreByIdSpec(StoreSeed.VALID_STORE_ID)); - result.Should().BeTrue(); - } + result.Should().BeTrue(); + } - [Fact] - public virtual async Task ReturnsFalse_GivenStoreByIdSpecWithInvalidStore() - { - var result = await storeRepository.AnyAsync(new StoreByIdSpec(0)); + [Fact] + public virtual async Task ReturnsFalse_GivenStoreByIdSpecWithInvalidStore() + { + var result = await storeRepository.AnyAsync(new StoreByIdSpec(0)); - result.Should().BeFalse(); - } + result.Should().BeFalse(); + } } diff --git a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/RepositoryOfT_AsAsyncEnumerable.cs b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/RepositoryOfT_AsAsyncEnumerable.cs index 0bca7580..32615b82 100644 --- a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/RepositoryOfT_AsAsyncEnumerable.cs +++ b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/RepositoryOfT_AsAsyncEnumerable.cs @@ -7,46 +7,46 @@ namespace Ardalis.Specification.EntityFrameworkCore.IntegrationTests; public class RepositoryOfT_AsAsyncEnumerable : RepositoryOfT_AnyAsync_TestKit { - public RepositoryOfT_AsAsyncEnumerable(SharedDatabaseFixture fixture) - : base(fixture, SpecificationEvaluator.Default) - { - } + public RepositoryOfT_AsAsyncEnumerable(SharedDatabaseFixture fixture) + : base(fixture, SpecificationEvaluator.Default) + { + } } public abstract class RepositoryOfT_AsAsyncEnumerable_TestKit : IntegrationTestBase { - protected RepositoryOfT_AsAsyncEnumerable_TestKit(SharedDatabaseFixture fixture, ISpecificationEvaluator specificationEvaluator) - : base(fixture, specificationEvaluator) - { - } - - [Fact] - public virtual async Task ReturnsTrueOnStoresRecords_WithoutSpec() - { - var results = storeRepository.AsAsyncEnumerable(new StoreIncludeProductsSpec()); - - await foreach (var result in results.WithCancellation(CancellationToken.None)) + protected RepositoryOfT_AsAsyncEnumerable_TestKit(SharedDatabaseFixture fixture, ISpecificationEvaluator specificationEvaluator) + : base(fixture, specificationEvaluator) { - result.Should().NotBeNull(); - result.Products.Should().NotBeEmpty(); } - } - [Fact] - public virtual async Task ReturnsStoreWithIdFrom15To30_GivenStoresByIdAsAsyncEnumerableSpec() - { - var ids = Enumerable.Range(15, 16); - var spec = new StoresByIdListSpec(ids); - - var counter = 0; - var results = storeRepository.AsAsyncEnumerable(spec); - await foreach (var result in results.WithCancellation(CancellationToken.None)) + [Fact] + public virtual async Task ReturnsTrueOnStoresRecords_WithoutSpec() { - result.Should().NotBeNull(); - result.Products.Should().NotBeEmpty(); - ++counter; + var results = storeRepository.AsAsyncEnumerable(new StoreIncludeProductsSpec()); + + await foreach (var result in results.WithCancellation(CancellationToken.None)) + { + result.Should().NotBeNull(); + result.Products.Should().NotBeEmpty(); + } } - counter.Should().Be(16); - } + [Fact] + public virtual async Task ReturnsStoreWithIdFrom15To30_GivenStoresByIdAsAsyncEnumerableSpec() + { + var ids = Enumerable.Range(15, 16); + var spec = new StoresByIdListSpec(ids); + + var counter = 0; + var results = storeRepository.AsAsyncEnumerable(spec); + await foreach (var result in results.WithCancellation(CancellationToken.None)) + { + result.Should().NotBeNull(); + result.Products.Should().NotBeEmpty(); + ++counter; + } + + counter.Should().Be(16); + } } diff --git a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/RepositoryOfT_GetById.cs b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/RepositoryOfT_GetById.cs index 65f991e6..74b55d07 100644 --- a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/RepositoryOfT_GetById.cs +++ b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/RepositoryOfT_GetById.cs @@ -7,37 +7,37 @@ namespace Ardalis.Specification.EntityFrameworkCore.IntegrationTests; public class RepositoryOfT_GetById : RepositoryOfT_GetById_TestKit { - public RepositoryOfT_GetById(SharedDatabaseFixture fixture) : base(fixture, SpecificationEvaluator.Default) - { - } + public RepositoryOfT_GetById(SharedDatabaseFixture fixture) : base(fixture, SpecificationEvaluator.Default) + { + } } public class RepositoryOfT_GetById_Cached : RepositoryOfT_GetById_TestKit { - public RepositoryOfT_GetById_Cached(SharedDatabaseFixture fixture) : base(fixture, SpecificationEvaluator.Cached) - { - } + public RepositoryOfT_GetById_Cached(SharedDatabaseFixture fixture) : base(fixture, SpecificationEvaluator.Cached) + { + } } public abstract class RepositoryOfT_GetById_TestKit : IntegrationTestBase { - protected RepositoryOfT_GetById_TestKit(SharedDatabaseFixture fixture, ISpecificationEvaluator specificationEvaluator) : base(fixture, specificationEvaluator) { } + protected RepositoryOfT_GetById_TestKit(SharedDatabaseFixture fixture, ISpecificationEvaluator specificationEvaluator) : base(fixture, specificationEvaluator) { } - [Fact] - public virtual async Task ReturnsStore_GivenId() - { - var result = await storeRepository.GetByIdAsync(StoreSeed.VALID_STORE_ID); + [Fact] + public virtual async Task ReturnsStore_GivenId() + { + var result = await storeRepository.GetByIdAsync(StoreSeed.VALID_STORE_ID); - result.Should().NotBeNull(); - result!.Name.Should().Be(StoreSeed.VALID_STORE_NAME); - } + result.Should().NotBeNull(); + result!.Name.Should().Be(StoreSeed.VALID_STORE_NAME); + } - [Fact] - public virtual async Task ReturnsStore_GivenGenericId() - { - var result = await storeRepository.GetByIdAsync(StoreSeed.VALID_STORE_ID); + [Fact] + public virtual async Task ReturnsStore_GivenGenericId() + { + var result = await storeRepository.GetByIdAsync(StoreSeed.VALID_STORE_ID); - result.Should().NotBeNull(); - result!.Name.Should().Be(StoreSeed.VALID_STORE_NAME); - } + result.Should().NotBeNull(); + result!.Name.Should().Be(StoreSeed.VALID_STORE_NAME); + } } diff --git a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/RepositoryOfT_GetBySpec.cs b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/RepositoryOfT_GetBySpec.cs index 03c89e24..afab280c 100644 --- a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/RepositoryOfT_GetBySpec.cs +++ b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/RepositoryOfT_GetBySpec.cs @@ -8,107 +8,107 @@ namespace Ardalis.Specification.EntityFrameworkCore.IntegrationTests; public class RepositoryOfT_GetBySpec : RepositoryOfT_GetBySpec_TestKit { - public RepositoryOfT_GetBySpec(SharedDatabaseFixture fixture) : base(fixture, SpecificationEvaluator.Default) - { - } + public RepositoryOfT_GetBySpec(SharedDatabaseFixture fixture) : base(fixture, SpecificationEvaluator.Default) + { + } } public class RepositoryOfT_GetBySpec_Cached : RepositoryOfT_GetBySpec_TestKit { - public RepositoryOfT_GetBySpec_Cached(SharedDatabaseFixture fixture) : base(fixture, SpecificationEvaluator.Cached) - { - } + public RepositoryOfT_GetBySpec_Cached(SharedDatabaseFixture fixture) : base(fixture, SpecificationEvaluator.Cached) + { + } } public abstract class RepositoryOfT_GetBySpec_TestKit : IntegrationTestBase { - protected RepositoryOfT_GetBySpec_TestKit(SharedDatabaseFixture fixture, ISpecificationEvaluator specificationEvaluator) : base(fixture, specificationEvaluator) { } - - [Fact] - public virtual async Task ReturnsStoreWithProducts_GivenStoreByIdIncludeProductsSpec() - { - var result = await storeRepository.GetBySpecAsync(new StoreByIdIncludeProductsSpec(StoreSeed.VALID_STORE_ID)); - - result.Should().NotBeNull(); - result!.Name.Should().Be(StoreSeed.VALID_STORE_NAME); - result.Products.Count.Should().BeGreaterThan(1); - } - - [Fact] - public virtual async Task ReturnsStoreWithAddress_GivenStoreByIdIncludeAddressSpec() - { - var result = await storeRepository.GetBySpecAsync(new StoreByIdIncludeAddressSpec(StoreSeed.VALID_STORE_ID)); - - result.Should().NotBeNull(); - result!.Name.Should().Be(StoreSeed.VALID_STORE_NAME); - result.Address?.Street.Should().Be(AddressSeed.VALID_STREET_FOR_STOREID1); - } - - [Fact] - public virtual async Task ReturnsStoreWithAddressAndProduct_GivenStoreByIdIncludeAddressAndProductsSpec() - { - var result = await storeRepository.GetBySpecAsync(new StoreByIdIncludeAddressAndProductsSpec(StoreSeed.VALID_STORE_ID)); - - result.Should().NotBeNull(); - result!.Name.Should().Be(StoreSeed.VALID_STORE_NAME); - result.Products.Count.Should().BeGreaterThan(1); - result.Address?.Street.Should().Be(AddressSeed.VALID_STREET_FOR_STOREID1); - } - - [Fact] - public virtual async Task ReturnsStoreWithProducts_GivenStoreByIdIncludeProductsUsingStringSpec() - { - var result = await storeRepository.GetBySpecAsync(new StoreByIdIncludeProductsUsingStringSpec(StoreSeed.VALID_STORE_ID)); - - result.Should().NotBeNull(); - result!.Name.Should().Be(StoreSeed.VALID_STORE_NAME); - result.Products.Count.Should().BeGreaterThan(1); - } - - [Fact] - public virtual async Task ReturnsCompanyWithStoresAndAddress_GivenCompanyByIdIncludeStoresThenIncludeAddressSpec() - { - var result = await companyRepository.GetBySpecAsync(new CompanyByIdIncludeStoresThenIncludeAddressSpec(CompanySeed.VALID_COMPANY_ID)); - - result.Should().NotBeNull(); - result!.Name.Should().Be(CompanySeed.VALID_COMPANY_NAME); - result.Stores.Count.Should().BeGreaterThan(49); - result.Stores.Select(x => x.Address).Count().Should().BeGreaterThan(0); - } - - [Fact] - public virtual async Task ReturnsCompanyWithStoresAndProducts_GivenCompanyByIdIncludeStoresThenIncludeProductsSpec() - { - var result = await companyRepository.GetBySpecAsync(new CompanyByIdIncludeStoresThenIncludeProductsSpec(CompanySeed.VALID_COMPANY_ID)); - - result.Should().NotBeNull(); - result!.Name.Should().Be(CompanySeed.VALID_COMPANY_NAME); - result.Stores.Count.Should().BeGreaterThan(49); - result.Stores.Select(x => x.Products).Count().Should().BeGreaterThan(1); - } - - [Fact] - public virtual async Task ReturnsUntrackedCompany_GivenCompanyByIdAsUntrackedSpec() - { - dbContext.ChangeTracker.Clear(); - - var result = await companyRepository.GetBySpecAsync(new CompanyByIdAsUntrackedSpec(CompanySeed.VALID_COMPANY_ID)); - - result.Should().NotBeNull(); - result?.Name.Should().Be(CompanySeed.VALID_COMPANY_NAME); - dbContext.Entry(result!).State.Should().Be(Microsoft.EntityFrameworkCore.EntityState.Detached); - } - - [Fact] - public virtual async Task ReturnsStoreWithCompanyAndCountryAndStoresForCompany_GivenStoreByIdIncludeCompanyAndCountryAndStoresForCompanySpec() - { - var result = await storeRepository.GetBySpecAsync(new StoreByIdIncludeCompanyAndCountryAndStoresForCompanySpec(StoreSeed.VALID_STORE_ID)); - - result.Should().NotBeNull(); - result!.Name.Should().Be(StoreSeed.VALID_STORE_NAME); - result.Company.Should().NotBeNull(); - result.Company!.Country.Should().NotBeNull(); - result.Company!.Stores.Should().HaveCountGreaterOrEqualTo(2); - result.Company?.Stores?.Should().Match(x => x.Any(z => z.Products.Count > 0)); - } + protected RepositoryOfT_GetBySpec_TestKit(SharedDatabaseFixture fixture, ISpecificationEvaluator specificationEvaluator) : base(fixture, specificationEvaluator) { } + + [Fact] + public virtual async Task ReturnsStoreWithProducts_GivenStoreByIdIncludeProductsSpec() + { + var result = await storeRepository.GetBySpecAsync(new StoreByIdIncludeProductsSpec(StoreSeed.VALID_STORE_ID)); + + result.Should().NotBeNull(); + result!.Name.Should().Be(StoreSeed.VALID_STORE_NAME); + result.Products.Count.Should().BeGreaterThan(1); + } + + [Fact] + public virtual async Task ReturnsStoreWithAddress_GivenStoreByIdIncludeAddressSpec() + { + var result = await storeRepository.GetBySpecAsync(new StoreByIdIncludeAddressSpec(StoreSeed.VALID_STORE_ID)); + + result.Should().NotBeNull(); + result!.Name.Should().Be(StoreSeed.VALID_STORE_NAME); + result.Address?.Street.Should().Be(AddressSeed.VALID_STREET_FOR_STOREID1); + } + + [Fact] + public virtual async Task ReturnsStoreWithAddressAndProduct_GivenStoreByIdIncludeAddressAndProductsSpec() + { + var result = await storeRepository.GetBySpecAsync(new StoreByIdIncludeAddressAndProductsSpec(StoreSeed.VALID_STORE_ID)); + + result.Should().NotBeNull(); + result!.Name.Should().Be(StoreSeed.VALID_STORE_NAME); + result.Products.Count.Should().BeGreaterThan(1); + result.Address?.Street.Should().Be(AddressSeed.VALID_STREET_FOR_STOREID1); + } + + [Fact] + public virtual async Task ReturnsStoreWithProducts_GivenStoreByIdIncludeProductsUsingStringSpec() + { + var result = await storeRepository.GetBySpecAsync(new StoreByIdIncludeProductsUsingStringSpec(StoreSeed.VALID_STORE_ID)); + + result.Should().NotBeNull(); + result!.Name.Should().Be(StoreSeed.VALID_STORE_NAME); + result.Products.Count.Should().BeGreaterThan(1); + } + + [Fact] + public virtual async Task ReturnsCompanyWithStoresAndAddress_GivenCompanyByIdIncludeStoresThenIncludeAddressSpec() + { + var result = await companyRepository.GetBySpecAsync(new CompanyByIdIncludeStoresThenIncludeAddressSpec(CompanySeed.VALID_COMPANY_ID)); + + result.Should().NotBeNull(); + result!.Name.Should().Be(CompanySeed.VALID_COMPANY_NAME); + result.Stores.Count.Should().BeGreaterThan(49); + result.Stores.Select(x => x.Address).Count().Should().BeGreaterThan(0); + } + + [Fact] + public virtual async Task ReturnsCompanyWithStoresAndProducts_GivenCompanyByIdIncludeStoresThenIncludeProductsSpec() + { + var result = await companyRepository.GetBySpecAsync(new CompanyByIdIncludeStoresThenIncludeProductsSpec(CompanySeed.VALID_COMPANY_ID)); + + result.Should().NotBeNull(); + result!.Name.Should().Be(CompanySeed.VALID_COMPANY_NAME); + result.Stores.Count.Should().BeGreaterThan(49); + result.Stores.Select(x => x.Products).Count().Should().BeGreaterThan(1); + } + + [Fact] + public virtual async Task ReturnsUntrackedCompany_GivenCompanyByIdAsUntrackedSpec() + { + dbContext.ChangeTracker.Clear(); + + var result = await companyRepository.GetBySpecAsync(new CompanyByIdAsUntrackedSpec(CompanySeed.VALID_COMPANY_ID)); + + result.Should().NotBeNull(); + result?.Name.Should().Be(CompanySeed.VALID_COMPANY_NAME); + dbContext.Entry(result!).State.Should().Be(Microsoft.EntityFrameworkCore.EntityState.Detached); + } + + [Fact] + public virtual async Task ReturnsStoreWithCompanyAndCountryAndStoresForCompany_GivenStoreByIdIncludeCompanyAndCountryAndStoresForCompanySpec() + { + var result = await storeRepository.GetBySpecAsync(new StoreByIdIncludeCompanyAndCountryAndStoresForCompanySpec(StoreSeed.VALID_STORE_ID)); + + result.Should().NotBeNull(); + result!.Name.Should().Be(StoreSeed.VALID_STORE_NAME); + result.Company.Should().NotBeNull(); + result.Company!.Country.Should().NotBeNull(); + result.Company!.Stores.Should().HaveCountGreaterOrEqualTo(2); + result.Company?.Stores?.Should().Match(x => x.Any(z => z.Products.Count > 0)); + } } diff --git a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/RepositoryOfT_ListAsync.cs b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/RepositoryOfT_ListAsync.cs index f4cde4f4..77f12ce1 100644 --- a/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/RepositoryOfT_ListAsync.cs +++ b/Specification.EntityFrameworkCore/tests/Ardalis.Specification.EntityFrameworkCore.IntegrationTests/RepositoryOfT_ListAsync.cs @@ -8,200 +8,200 @@ namespace Ardalis.Specification.EntityFrameworkCore.IntegrationTests; public class RepositoryOfT_ListAsync : RepositoryOfT_ListAsync_TestKit { - public RepositoryOfT_ListAsync(SharedDatabaseFixture fixture) : base(fixture, SpecificationEvaluator.Default) - { - } + public RepositoryOfT_ListAsync(SharedDatabaseFixture fixture) : base(fixture, SpecificationEvaluator.Default) + { + } } public class RepositoryOfT_ListAsync_Cached : RepositoryOfT_ListAsync_TestKit { - public RepositoryOfT_ListAsync_Cached(SharedDatabaseFixture fixture) : base(fixture, SpecificationEvaluator.Cached) - { - } + public RepositoryOfT_ListAsync_Cached(SharedDatabaseFixture fixture) : base(fixture, SpecificationEvaluator.Cached) + { + } } public abstract class RepositoryOfT_ListAsync_TestKit : IntegrationTestBase { - protected RepositoryOfT_ListAsync_TestKit(SharedDatabaseFixture fixture, ISpecificationEvaluator specificationEvaluator) : base(fixture, specificationEvaluator) { } - - [Fact] - public virtual async Task ReturnsStoreWithProducts_GivenStoreIncludeProductsSpec() - { - var result = await storeRepository.ListAsync(new StoreIncludeProductsSpec()); - - result.Should().NotBeNull(); - result.Should().NotBeEmpty(); - result[0].Products.Should().NotBeEmpty(); - } - - [Fact] - public virtual async Task ReturnsStoreWithAddress_GivenStoreIncludeAddressSpec() - { - var result = await storeRepository.ListAsync(new StoreIncludeAddressSpec()); - - result.Should().NotBeNull(); - result.Should().NotBeEmpty(); - result[0].Address.Should().NotBeNull(); - } - - [Fact] - public virtual async Task ReturnsStoreWithAddressAndProduct_GivenStoreIncludeAddressAndProductsSpec() - { - var result = await storeRepository.ListAsync(new StoreIncludeAddressAndProductsSpec()); - - result.Should().NotBeNull(); - result.Should().NotBeEmpty(); - result[0].Address.Should().NotBeNull(); - result[0].Products.Should().NotBeEmpty(); - } - - [Fact] - public virtual async Task ReturnsCompanyWithStoreWithIdOne_GivenCompanyIncludeFilteredStoresSpec() - { - var result = await companyRepository.ListAsync(new CompanyIncludeFilteredStoresSpec(1)); - - result.Should().NotBeNull(); - result.Should().NotBeEmpty(); - result[0].Stores.Should().NotBeEmpty(); - result[0].Stores.Should().HaveCount(1); - result[0].Stores.First().Id.Should().Be(1); - } - - [Fact] - public virtual async Task ReturnsStoreWithIdFrom15To30_GivenStoresByIdListSpec() - { - var ids = Enumerable.Range(15, 16); - var spec = new StoresByIdListSpec(ids); + protected RepositoryOfT_ListAsync_TestKit(SharedDatabaseFixture fixture, ISpecificationEvaluator specificationEvaluator) : base(fixture, specificationEvaluator) { } + + [Fact] + public virtual async Task ReturnsStoreWithProducts_GivenStoreIncludeProductsSpec() + { + var result = await storeRepository.ListAsync(new StoreIncludeProductsSpec()); + + result.Should().NotBeNull(); + result.Should().NotBeEmpty(); + result[0].Products.Should().NotBeEmpty(); + } + + [Fact] + public virtual async Task ReturnsStoreWithAddress_GivenStoreIncludeAddressSpec() + { + var result = await storeRepository.ListAsync(new StoreIncludeAddressSpec()); + + result.Should().NotBeNull(); + result.Should().NotBeEmpty(); + result[0].Address.Should().NotBeNull(); + } + + [Fact] + public virtual async Task ReturnsStoreWithAddressAndProduct_GivenStoreIncludeAddressAndProductsSpec() + { + var result = await storeRepository.ListAsync(new StoreIncludeAddressAndProductsSpec()); + + result.Should().NotBeNull(); + result.Should().NotBeEmpty(); + result[0].Address.Should().NotBeNull(); + result[0].Products.Should().NotBeEmpty(); + } + + [Fact] + public virtual async Task ReturnsCompanyWithStoreWithIdOne_GivenCompanyIncludeFilteredStoresSpec() + { + var result = await companyRepository.ListAsync(new CompanyIncludeFilteredStoresSpec(1)); + + result.Should().NotBeNull(); + result.Should().NotBeEmpty(); + result[0].Stores.Should().NotBeEmpty(); + result[0].Stores.Should().HaveCount(1); + result[0].Stores.First().Id.Should().Be(1); + } + + [Fact] + public virtual async Task ReturnsStoreWithIdFrom15To30_GivenStoresByIdListSpec() + { + var ids = Enumerable.Range(15, 16); + var spec = new StoresByIdListSpec(ids); - var stores = await storeRepository.ListAsync(spec); - - stores.Count.Should().Be(16); - stores.OrderBy(x => x.Id).First().Id.Should().Be(15); - stores.OrderBy(x => x.Id).Last().Id.Should().Be(30); - } + var stores = await storeRepository.ListAsync(spec); + + stores.Count.Should().Be(16); + stores.OrderBy(x => x.Id).First().Id.Should().Be(15); + stores.OrderBy(x => x.Id).Last().Id.Should().Be(30); + } - [Fact] - public virtual async Task ReturnsSecondPageOfStoreNames_GivenStoreNamesPaginatedSpec() - { - var take = 10; // pagesize 10 - var skip = (2 - 1) * 10; // page 2 - - var spec = new StoreNamesPaginatedSpec(skip, take); - - var storeNames = await storeRepository.ListAsync(spec); - - storeNames.Count.Should().Be(take); - storeNames.First().Should().Be("Store 11"); - storeNames.Last().Should().Be("Store 20"); - } - - [Fact] - public virtual async Task ReturnsSecondPageOfStores_GivenStoresPaginatedSpec() - { - var take = 10; // pagesize 10 - var skip = (2 - 1) * 10; // page 2 - - var spec = new StoresPaginatedSpec(skip, take); - - var stores = await storeRepository.ListAsync(spec); - - stores.Count.Should().Be(take); - stores.OrderBy(x => x.Id).First().Id.Should().Be(11); - stores.OrderBy(x => x.Id).Last().Id.Should().Be(20); - } - - [Fact] - public virtual async Task ReturnsOrderStoresByNameDescForCompanyWithId2_GivenStoresByCompanyOrderedDescByNameSpec() - { - var spec = new StoresByCompanyOrderedDescByNameSpec(2); - - var stores = await storeRepository.ListAsync(spec); - - stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_FIRST_ID); - stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_LAST_ID); - } - - [Fact] - public virtual async Task ReturnsOrderStoresByNameDescThenByIdForCompanyWithId2_GivenStoresByCompanyOrderedDescByNameThenByIdSpec() - { - var spec = new StoresByCompanyOrderedDescByNameThenByIdSpec(2); - - var stores = await storeRepository.ListAsync(spec); - - stores.First().Id.Should().Be(99); - stores.Last().Id.Should().Be(98); - } - - [Fact] - public virtual async Task ReturnsSecondPageOfStoresForCompanyWithId2_GivenStoresByCompanyPaginatedOrderedDescByNameSpec() - { - var take = 10; // pagesize 10 - var skip = (2 - 1) * 10; // page 2 - - var spec = new StoresByCompanyPaginatedOrderedDescByNameSpec(2, skip, take); - - var stores = await storeRepository.ListAsync(spec); - - stores.Count.Should().Be(take); - stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_PAGE2_FIRST_ID); - stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_PAGE2_LAST_ID); - } - - [Fact] - public virtual async Task ReturnsSecondPageOfStoresForCompanyWithId2_GivenStoresByCompanyPaginatedSpec() - { - var take = 10; // pagesize 10 - var skip = (2 - 1) * 10; // page 2 - - var spec = new StoresByCompanyPaginatedSpec(2, skip, take); + [Fact] + public virtual async Task ReturnsSecondPageOfStoreNames_GivenStoreNamesPaginatedSpec() + { + var take = 10; // pagesize 10 + var skip = (2 - 1) * 10; // page 2 + + var spec = new StoreNamesPaginatedSpec(skip, take); + + var storeNames = await storeRepository.ListAsync(spec); + + storeNames.Count.Should().Be(take); + storeNames.First().Should().Be("Store 11"); + storeNames.Last().Should().Be("Store 20"); + } + + [Fact] + public virtual async Task ReturnsSecondPageOfStores_GivenStoresPaginatedSpec() + { + var take = 10; // pagesize 10 + var skip = (2 - 1) * 10; // page 2 + + var spec = new StoresPaginatedSpec(skip, take); + + var stores = await storeRepository.ListAsync(spec); + + stores.Count.Should().Be(take); + stores.OrderBy(x => x.Id).First().Id.Should().Be(11); + stores.OrderBy(x => x.Id).Last().Id.Should().Be(20); + } + + [Fact] + public virtual async Task ReturnsOrderStoresByNameDescForCompanyWithId2_GivenStoresByCompanyOrderedDescByNameSpec() + { + var spec = new StoresByCompanyOrderedDescByNameSpec(2); + + var stores = await storeRepository.ListAsync(spec); + + stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_FIRST_ID); + stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_LAST_ID); + } + + [Fact] + public virtual async Task ReturnsOrderStoresByNameDescThenByIdForCompanyWithId2_GivenStoresByCompanyOrderedDescByNameThenByIdSpec() + { + var spec = new StoresByCompanyOrderedDescByNameThenByIdSpec(2); + + var stores = await storeRepository.ListAsync(spec); + + stores.First().Id.Should().Be(99); + stores.Last().Id.Should().Be(98); + } + + [Fact] + public virtual async Task ReturnsSecondPageOfStoresForCompanyWithId2_GivenStoresByCompanyPaginatedOrderedDescByNameSpec() + { + var take = 10; // pagesize 10 + var skip = (2 - 1) * 10; // page 2 + + var spec = new StoresByCompanyPaginatedOrderedDescByNameSpec(2, skip, take); + + var stores = await storeRepository.ListAsync(spec); + + stores.Count.Should().Be(take); + stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_PAGE2_FIRST_ID); + stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_PAGE2_LAST_ID); + } + + [Fact] + public virtual async Task ReturnsSecondPageOfStoresForCompanyWithId2_GivenStoresByCompanyPaginatedSpec() + { + var take = 10; // pagesize 10 + var skip = (2 - 1) * 10; // page 2 + + var spec = new StoresByCompanyPaginatedSpec(2, skip, take); - var stores = await storeRepository.ListAsync(spec); - - stores.Count.Should().Be(take); - stores.OrderBy(x => x.Id).First().Id.Should().Be(61); - stores.OrderBy(x => x.Id).Last().Id.Should().Be(70); - } + var stores = await storeRepository.ListAsync(spec); + + stores.Count.Should().Be(take); + stores.OrderBy(x => x.Id).First().Id.Should().Be(61); + stores.OrderBy(x => x.Id).Last().Id.Should().Be(70); + } - [Fact] - public virtual async Task ReturnsOrderedStores_GivenStoresOrderedSpecByName() - { - var spec = new StoresOrderedSpecByName(); + [Fact] + public virtual async Task ReturnsOrderedStores_GivenStoresOrderedSpecByName() + { + var spec = new StoresOrderedSpecByName(); - var stores = await storeRepository.ListAsync(spec); + var stores = await storeRepository.ListAsync(spec); - stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_FIRST_ID); - stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_LAST_ID); - } + stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_FIRST_ID); + stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_LAST_ID); + } - [Fact] - public virtual async Task ReturnsOrderedStores_GivenStoresOrderedDescendingByNameSpec() - { - var spec = new StoresOrderedDescendingByNameSpec(); + [Fact] + public virtual async Task ReturnsOrderedStores_GivenStoresOrderedDescendingByNameSpec() + { + var spec = new StoresOrderedDescendingByNameSpec(); - var stores = await storeRepository.ListAsync(spec); + var stores = await storeRepository.ListAsync(spec); - stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FIRST_ID); - stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_LAST_ID); - } + stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FIRST_ID); + stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_LAST_ID); + } - [Fact] - public virtual async Task ReturnsStoreContainingCity1_GivenStoreIncludeProductsSpec() - { - var result = await storeRepository.ListAsync(new StoreSearchByNameOrCitySpec(StoreSeed.VALID_Search_City_Key)); + [Fact] + public virtual async Task ReturnsStoreContainingCity1_GivenStoreIncludeProductsSpec() + { + var result = await storeRepository.ListAsync(new StoreSearchByNameOrCitySpec(StoreSeed.VALID_Search_City_Key)); - result.Should().NotBeNull(); - result.Should().ContainSingle(); - result[0].Id.Should().Be(StoreSeed.VALID_Search_ID); - result[0].City.Should().Contain(StoreSeed.VALID_Search_City_Key); - } + result.Should().NotBeNull(); + result.Should().ContainSingle(); + result[0].Id.Should().Be(StoreSeed.VALID_Search_ID); + result[0].City.Should().Contain(StoreSeed.VALID_Search_City_Key); + } - [Fact] - public virtual async Task ReturnsAllProducts_GivenStoreSelectManyProductsSpec() - { - var result = await storeRepository.ListAsync(new StoreProductNamesSpec()); + [Fact] + public virtual async Task ReturnsAllProducts_GivenStoreSelectManyProductsSpec() + { + var result = await storeRepository.ListAsync(new StoreProductNamesSpec()); - result.Should().NotBeNull(); - result.Should().HaveCount(ProductSeed.TOTAL_PRODUCT_COUNT); - result.OrderBy(x => x).First().Should().Be(ProductSeed.VALID_PRODUCT_NAME); - } + result.Should().NotBeNull(); + result.Should().HaveCount(ProductSeed.TOTAL_PRODUCT_COUNT); + result.OrderBy(x => x).First().Should().Be(ProductSeed.VALID_PRODUCT_NAME); + } } diff --git a/Specification/src/Ardalis.Specification/Builder/CacheSpecificationBuilder.cs b/Specification/src/Ardalis.Specification/Builder/CacheSpecificationBuilder.cs index ad0e472a..c5691ecd 100644 --- a/Specification/src/Ardalis.Specification/Builder/CacheSpecificationBuilder.cs +++ b/Specification/src/Ardalis.Specification/Builder/CacheSpecificationBuilder.cs @@ -2,17 +2,17 @@ public class CacheSpecificationBuilder : ICacheSpecificationBuilder where T : class { - public Specification Specification { get; } - public bool IsChainDiscarded { get; set; } + public Specification Specification { get; } + public bool IsChainDiscarded { get; set; } - public CacheSpecificationBuilder(Specification specification) - : this(specification, false) - { - } + public CacheSpecificationBuilder(Specification specification) + : this(specification, false) + { + } - public CacheSpecificationBuilder(Specification specification, bool isChainDiscarded) - { - Specification = specification; - IsChainDiscarded = isChainDiscarded; - } + public CacheSpecificationBuilder(Specification specification, bool isChainDiscarded) + { + Specification = specification; + IsChainDiscarded = isChainDiscarded; + } } diff --git a/Specification/src/Ardalis.Specification/Builder/ICacheSpecificationBuilder.cs b/Specification/src/Ardalis.Specification/Builder/ICacheSpecificationBuilder.cs index c635a211..460deac7 100644 --- a/Specification/src/Ardalis.Specification/Builder/ICacheSpecificationBuilder.cs +++ b/Specification/src/Ardalis.Specification/Builder/ICacheSpecificationBuilder.cs @@ -2,5 +2,5 @@ public interface ICacheSpecificationBuilder : ISpecificationBuilder where T : class { - bool IsChainDiscarded { get; set; } + bool IsChainDiscarded { get; set; } } diff --git a/Specification/src/Ardalis.Specification/Builder/IIncludableSpecificationBuilder.cs b/Specification/src/Ardalis.Specification/Builder/IIncludableSpecificationBuilder.cs index df071c3f..07857e19 100644 --- a/Specification/src/Ardalis.Specification/Builder/IIncludableSpecificationBuilder.cs +++ b/Specification/src/Ardalis.Specification/Builder/IIncludableSpecificationBuilder.cs @@ -2,5 +2,5 @@ public interface IIncludableSpecificationBuilder : ISpecificationBuilder where T : class { - bool IsChainDiscarded { get; set; } + bool IsChainDiscarded { get; set; } } diff --git a/Specification/src/Ardalis.Specification/Builder/IOrderedSpecificationBuilder.cs b/Specification/src/Ardalis.Specification/Builder/IOrderedSpecificationBuilder.cs index 523c5d79..0039dd79 100644 --- a/Specification/src/Ardalis.Specification/Builder/IOrderedSpecificationBuilder.cs +++ b/Specification/src/Ardalis.Specification/Builder/IOrderedSpecificationBuilder.cs @@ -2,5 +2,5 @@ public interface IOrderedSpecificationBuilder : ISpecificationBuilder { - bool IsChainDiscarded { get; set; } + bool IsChainDiscarded { get; set; } } diff --git a/Specification/src/Ardalis.Specification/Builder/ISpecificationBuilder.cs b/Specification/src/Ardalis.Specification/Builder/ISpecificationBuilder.cs index 505ac8aa..dfeba22c 100644 --- a/Specification/src/Ardalis.Specification/Builder/ISpecificationBuilder.cs +++ b/Specification/src/Ardalis.Specification/Builder/ISpecificationBuilder.cs @@ -2,10 +2,10 @@ public interface ISpecificationBuilder : ISpecificationBuilder { - new Specification Specification { get; } + new Specification Specification { get; } } public interface ISpecificationBuilder { - Specification Specification { get; } + Specification Specification { get; } } diff --git a/Specification/src/Ardalis.Specification/Builder/IncludableBuilderExtensions.cs b/Specification/src/Ardalis.Specification/Builder/IncludableBuilderExtensions.cs index c2cefb19..ec72dc8f 100644 --- a/Specification/src/Ardalis.Specification/Builder/IncludableBuilderExtensions.cs +++ b/Specification/src/Ardalis.Specification/Builder/IncludableBuilderExtensions.cs @@ -6,51 +6,51 @@ namespace Ardalis.Specification; public static class IncludableBuilderExtensions { - public static IIncludableSpecificationBuilder ThenInclude( - this IIncludableSpecificationBuilder previousBuilder, - Expression> thenIncludeExpression) - where TEntity : class - => ThenInclude(previousBuilder, thenIncludeExpression, true); - - public static IIncludableSpecificationBuilder ThenInclude( - this IIncludableSpecificationBuilder previousBuilder, - Expression> thenIncludeExpression, - bool condition) - where TEntity : class - { - if (condition && !previousBuilder.IsChainDiscarded) + public static IIncludableSpecificationBuilder ThenInclude( + this IIncludableSpecificationBuilder previousBuilder, + Expression> thenIncludeExpression) + where TEntity : class + => ThenInclude(previousBuilder, thenIncludeExpression, true); + + public static IIncludableSpecificationBuilder ThenInclude( + this IIncludableSpecificationBuilder previousBuilder, + Expression> thenIncludeExpression, + bool condition) + where TEntity : class { - var info = new IncludeExpressionInfo(thenIncludeExpression, typeof(TEntity), typeof(TProperty), typeof(TPreviousProperty)); + if (condition && !previousBuilder.IsChainDiscarded) + { + var info = new IncludeExpressionInfo(thenIncludeExpression, typeof(TEntity), typeof(TProperty), typeof(TPreviousProperty)); - ((List)previousBuilder.Specification.IncludeExpressions).Add(info); - } - - var includeBuilder = new IncludableSpecificationBuilder(previousBuilder.Specification, !condition || previousBuilder.IsChainDiscarded); + ((List)previousBuilder.Specification.IncludeExpressions).Add(info); + } - return includeBuilder; - } + var includeBuilder = new IncludableSpecificationBuilder(previousBuilder.Specification, !condition || previousBuilder.IsChainDiscarded); - public static IIncludableSpecificationBuilder ThenInclude( - this IIncludableSpecificationBuilder> previousBuilder, - Expression> thenIncludeExpression) - where TEntity : class - => ThenInclude(previousBuilder, thenIncludeExpression, true); + return includeBuilder; + } - public static IIncludableSpecificationBuilder ThenInclude( - this IIncludableSpecificationBuilder> previousBuilder, - Expression> thenIncludeExpression, - bool condition) - where TEntity : class - { - if (condition && !previousBuilder.IsChainDiscarded) + public static IIncludableSpecificationBuilder ThenInclude( + this IIncludableSpecificationBuilder> previousBuilder, + Expression> thenIncludeExpression) + where TEntity : class + => ThenInclude(previousBuilder, thenIncludeExpression, true); + + public static IIncludableSpecificationBuilder ThenInclude( + this IIncludableSpecificationBuilder> previousBuilder, + Expression> thenIncludeExpression, + bool condition) + where TEntity : class { - var info = new IncludeExpressionInfo(thenIncludeExpression, typeof(TEntity), typeof(TProperty), typeof(IEnumerable)); + if (condition && !previousBuilder.IsChainDiscarded) + { + var info = new IncludeExpressionInfo(thenIncludeExpression, typeof(TEntity), typeof(TProperty), typeof(IEnumerable)); - ((List)previousBuilder.Specification.IncludeExpressions).Add(info); - } + ((List)previousBuilder.Specification.IncludeExpressions).Add(info); + } - var includeBuilder = new IncludableSpecificationBuilder(previousBuilder.Specification, !condition || previousBuilder.IsChainDiscarded); + var includeBuilder = new IncludableSpecificationBuilder(previousBuilder.Specification, !condition || previousBuilder.IsChainDiscarded); - return includeBuilder; - } + return includeBuilder; + } } diff --git a/Specification/src/Ardalis.Specification/Builder/IncludableSpecificationBuilder.cs b/Specification/src/Ardalis.Specification/Builder/IncludableSpecificationBuilder.cs index f89c76ed..f1686f50 100644 --- a/Specification/src/Ardalis.Specification/Builder/IncludableSpecificationBuilder.cs +++ b/Specification/src/Ardalis.Specification/Builder/IncludableSpecificationBuilder.cs @@ -2,17 +2,17 @@ public class IncludableSpecificationBuilder : IIncludableSpecificationBuilder where T : class { - public Specification Specification { get; } - public bool IsChainDiscarded { get; set; } + public Specification Specification { get; } + public bool IsChainDiscarded { get; set; } - public IncludableSpecificationBuilder(Specification specification) - : this(specification, false) - { - } + public IncludableSpecificationBuilder(Specification specification) + : this(specification, false) + { + } - public IncludableSpecificationBuilder(Specification specification, bool isChainDiscarded) - { - Specification = specification; - IsChainDiscarded = isChainDiscarded; - } + public IncludableSpecificationBuilder(Specification specification, bool isChainDiscarded) + { + Specification = specification; + IsChainDiscarded = isChainDiscarded; + } } diff --git a/Specification/src/Ardalis.Specification/Builder/OrderedBuilderExtensions.cs b/Specification/src/Ardalis.Specification/Builder/OrderedBuilderExtensions.cs index 3ab76eae..e6250361 100644 --- a/Specification/src/Ardalis.Specification/Builder/OrderedBuilderExtensions.cs +++ b/Specification/src/Ardalis.Specification/Builder/OrderedBuilderExtensions.cs @@ -6,47 +6,47 @@ namespace Ardalis.Specification; public static class OrderedBuilderExtensions { - public static IOrderedSpecificationBuilder ThenBy( - this IOrderedSpecificationBuilder orderedBuilder, - Expression> orderExpression) - => ThenBy(orderedBuilder, orderExpression, true); + public static IOrderedSpecificationBuilder ThenBy( + this IOrderedSpecificationBuilder orderedBuilder, + Expression> orderExpression) + => ThenBy(orderedBuilder, orderExpression, true); - public static IOrderedSpecificationBuilder ThenBy( - this IOrderedSpecificationBuilder orderedBuilder, - Expression> orderExpression, - bool condition) - { - if (condition && !orderedBuilder.IsChainDiscarded) + public static IOrderedSpecificationBuilder ThenBy( + this IOrderedSpecificationBuilder orderedBuilder, + Expression> orderExpression, + bool condition) { - ((List>)orderedBuilder.Specification.OrderExpressions).Add(new OrderExpressionInfo(orderExpression, OrderTypeEnum.ThenBy)); - } - else - { - orderedBuilder.IsChainDiscarded = true; - } + if (condition && !orderedBuilder.IsChainDiscarded) + { + ((List>)orderedBuilder.Specification.OrderExpressions).Add(new OrderExpressionInfo(orderExpression, OrderTypeEnum.ThenBy)); + } + else + { + orderedBuilder.IsChainDiscarded = true; + } - return orderedBuilder; - } + return orderedBuilder; + } - public static IOrderedSpecificationBuilder ThenByDescending( - this IOrderedSpecificationBuilder orderedBuilder, - Expression> orderExpression) - => ThenByDescending(orderedBuilder, orderExpression, true); + public static IOrderedSpecificationBuilder ThenByDescending( + this IOrderedSpecificationBuilder orderedBuilder, + Expression> orderExpression) + => ThenByDescending(orderedBuilder, orderExpression, true); - public static IOrderedSpecificationBuilder ThenByDescending( - this IOrderedSpecificationBuilder orderedBuilder, - Expression> orderExpression, - bool condition) - { - if (condition && !orderedBuilder.IsChainDiscarded) + public static IOrderedSpecificationBuilder ThenByDescending( + this IOrderedSpecificationBuilder orderedBuilder, + Expression> orderExpression, + bool condition) { - ((List>)orderedBuilder.Specification.OrderExpressions).Add(new OrderExpressionInfo(orderExpression, OrderTypeEnum.ThenByDescending)); - } - else - { - orderedBuilder.IsChainDiscarded = true; - } + if (condition && !orderedBuilder.IsChainDiscarded) + { + ((List>)orderedBuilder.Specification.OrderExpressions).Add(new OrderExpressionInfo(orderExpression, OrderTypeEnum.ThenByDescending)); + } + else + { + orderedBuilder.IsChainDiscarded = true; + } - return orderedBuilder; - } + return orderedBuilder; + } } diff --git a/Specification/src/Ardalis.Specification/Builder/OrderedSpecificationBuilder.cs b/Specification/src/Ardalis.Specification/Builder/OrderedSpecificationBuilder.cs index 66224d9a..7a319030 100644 --- a/Specification/src/Ardalis.Specification/Builder/OrderedSpecificationBuilder.cs +++ b/Specification/src/Ardalis.Specification/Builder/OrderedSpecificationBuilder.cs @@ -2,17 +2,17 @@ public class OrderedSpecificationBuilder : IOrderedSpecificationBuilder { - public Specification Specification { get; } - public bool IsChainDiscarded { get; set; } + public Specification Specification { get; } + public bool IsChainDiscarded { get; set; } - public OrderedSpecificationBuilder(Specification specification) - : this(specification, false) - { - } + public OrderedSpecificationBuilder(Specification specification) + : this(specification, false) + { + } - public OrderedSpecificationBuilder(Specification specification, bool isChainDiscarded) - { - Specification = specification; - IsChainDiscarded = isChainDiscarded; - } + public OrderedSpecificationBuilder(Specification specification, bool isChainDiscarded) + { + Specification = specification; + IsChainDiscarded = isChainDiscarded; + } } diff --git a/Specification/src/Ardalis.Specification/Builder/SpecificationBuilder.cs b/Specification/src/Ardalis.Specification/Builder/SpecificationBuilder.cs index 711c8725..b23eed0b 100644 --- a/Specification/src/Ardalis.Specification/Builder/SpecificationBuilder.cs +++ b/Specification/src/Ardalis.Specification/Builder/SpecificationBuilder.cs @@ -2,21 +2,21 @@ public class SpecificationBuilder : SpecificationBuilder, ISpecificationBuilder { - public new Specification Specification { get; } + public new Specification Specification { get; } - public SpecificationBuilder(Specification specification) - : base(specification) - { - Specification = specification; - } + public SpecificationBuilder(Specification specification) + : base(specification) + { + Specification = specification; + } } public class SpecificationBuilder : ISpecificationBuilder { - public Specification Specification { get; } + public Specification Specification { get; } - public SpecificationBuilder(Specification specification) - { - Specification = specification; - } + public SpecificationBuilder(Specification specification) + { + Specification = specification; + } } diff --git a/Specification/src/Ardalis.Specification/Builder/SpecificationBuilderExtensions.cs b/Specification/src/Ardalis.Specification/Builder/SpecificationBuilderExtensions.cs index 0c787420..74204a62 100644 --- a/Specification/src/Ardalis.Specification/Builder/SpecificationBuilderExtensions.cs +++ b/Specification/src/Ardalis.Specification/Builder/SpecificationBuilderExtensions.cs @@ -6,532 +6,532 @@ namespace Ardalis.Specification; public static class SpecificationBuilderExtensions { - /// - /// Specify a predicate that will be applied to the query - /// - /// - /// - /// - public static ISpecificationBuilder Where( - this ISpecificationBuilder specificationBuilder, - Expression> criteria) - => Where(specificationBuilder, criteria, true); - - /// - /// Specify a predicate that will be applied to the query - /// - /// - /// - /// - /// If false, the criteria won't be added. - public static ISpecificationBuilder Where( - this ISpecificationBuilder specificationBuilder, - Expression> criteria, - bool condition) - { - if (condition) + /// + /// Specify a predicate that will be applied to the query + /// + /// + /// + /// + public static ISpecificationBuilder Where( + this ISpecificationBuilder specificationBuilder, + Expression> criteria) + => Where(specificationBuilder, criteria, true); + + /// + /// Specify a predicate that will be applied to the query + /// + /// + /// + /// + /// If false, the criteria won't be added. + public static ISpecificationBuilder Where( + this ISpecificationBuilder specificationBuilder, + Expression> criteria, + bool condition) { - ((List>)specificationBuilder.Specification.WhereExpressions).Add(new WhereExpressionInfo(criteria)); + if (condition) + { + ((List>)specificationBuilder.Specification.WhereExpressions).Add(new WhereExpressionInfo(criteria)); + } + + return specificationBuilder; + } + + /// + /// Specify the query result will be ordered by in an ascending order + /// + /// + /// + /// + public static IOrderedSpecificationBuilder OrderBy( + this ISpecificationBuilder specificationBuilder, + Expression> orderExpression) + => OrderBy(specificationBuilder, orderExpression, true); + + /// + /// Specify the query result will be ordered by in an ascending order + /// + /// + /// + /// + /// If false, the expression won't be added. The whole Order chain will be discarded. + public static IOrderedSpecificationBuilder OrderBy( + this ISpecificationBuilder specificationBuilder, + Expression> orderExpression, + bool condition) + { + if (condition) + { + ((List>)specificationBuilder.Specification.OrderExpressions).Add(new OrderExpressionInfo(orderExpression, OrderTypeEnum.OrderBy)); + } + + var orderedSpecificationBuilder = new OrderedSpecificationBuilder(specificationBuilder.Specification, !condition); + + return orderedSpecificationBuilder; } - return specificationBuilder; - } - - /// - /// Specify the query result will be ordered by in an ascending order - /// - /// - /// - /// - public static IOrderedSpecificationBuilder OrderBy( - this ISpecificationBuilder specificationBuilder, - Expression> orderExpression) - => OrderBy(specificationBuilder, orderExpression, true); - - /// - /// Specify the query result will be ordered by in an ascending order - /// - /// - /// - /// - /// If false, the expression won't be added. The whole Order chain will be discarded. - public static IOrderedSpecificationBuilder OrderBy( - this ISpecificationBuilder specificationBuilder, - Expression> orderExpression, - bool condition) - { - if (condition) + /// + /// Specify the query result will be ordered by in a descending order + /// + /// + /// + /// + public static IOrderedSpecificationBuilder OrderByDescending( + this ISpecificationBuilder specificationBuilder, + Expression> orderExpression) + => OrderByDescending(specificationBuilder, orderExpression, true); + + /// + /// Specify the query result will be ordered by in a descending order + /// + /// + /// + /// + /// If false, the expression won't be added. The whole Order chain will be discarded. + public static IOrderedSpecificationBuilder OrderByDescending( + this ISpecificationBuilder specificationBuilder, + Expression> orderExpression, + bool condition) { - ((List>)specificationBuilder.Specification.OrderExpressions).Add(new OrderExpressionInfo(orderExpression, OrderTypeEnum.OrderBy)); + if (condition) + { + ((List>)specificationBuilder.Specification.OrderExpressions).Add(new OrderExpressionInfo(orderExpression, OrderTypeEnum.OrderByDescending)); + } + + var orderedSpecificationBuilder = new OrderedSpecificationBuilder(specificationBuilder.Specification, !condition); + + return orderedSpecificationBuilder; } - var orderedSpecificationBuilder = new OrderedSpecificationBuilder(specificationBuilder.Specification, !condition); - - return orderedSpecificationBuilder; - } - - /// - /// Specify the query result will be ordered by in a descending order - /// - /// - /// - /// - public static IOrderedSpecificationBuilder OrderByDescending( - this ISpecificationBuilder specificationBuilder, - Expression> orderExpression) - => OrderByDescending(specificationBuilder, orderExpression, true); - - /// - /// Specify the query result will be ordered by in a descending order - /// - /// - /// - /// - /// If false, the expression won't be added. The whole Order chain will be discarded. - public static IOrderedSpecificationBuilder OrderByDescending( - this ISpecificationBuilder specificationBuilder, - Expression> orderExpression, - bool condition) - { - if (condition) + /// + /// Specify an include expression. + /// This information is utilized to build Include function in the query, which ORM tools like Entity Framework use + /// to include related entities (via navigation properties) in the query result. + /// + /// + /// + /// + /// + public static IIncludableSpecificationBuilder Include( + this ISpecificationBuilder specificationBuilder, + Expression> includeExpression) where T : class + => Include(specificationBuilder, includeExpression, true); + + /// + /// Specify an include expression. + /// This information is utilized to build Include function in the query, which ORM tools like Entity Framework use + /// to include related entities (via navigation properties) in the query result. + /// + /// + /// + /// + /// + /// If false, the expression won't be added. The whole Include chain will be discarded. + public static IIncludableSpecificationBuilder Include( + this ISpecificationBuilder specificationBuilder, + Expression> includeExpression, + bool condition) where T : class { - ((List>)specificationBuilder.Specification.OrderExpressions).Add(new OrderExpressionInfo(orderExpression, OrderTypeEnum.OrderByDescending)); + if (condition) + { + var info = new IncludeExpressionInfo(includeExpression, typeof(T), typeof(TProperty)); + + ((List)specificationBuilder.Specification.IncludeExpressions).Add(info); + } + + var includeBuilder = new IncludableSpecificationBuilder(specificationBuilder.Specification, !condition); + + return includeBuilder; + } + + /// + /// Specify a collection of navigation properties, as strings, to include in the query. + /// + /// + /// + /// + public static ISpecificationBuilder Include( + this ISpecificationBuilder specificationBuilder, + string includeString) where T : class + => Include(specificationBuilder, includeString, true); + + /// + /// Specify a collection of navigation properties, as strings, to include in the query. + /// + /// + /// + /// + /// If false, the include expression won't be added. + public static ISpecificationBuilder Include( + this ISpecificationBuilder specificationBuilder, + string includeString, + bool condition) where T : class + { + if (condition) + { + ((List)specificationBuilder.Specification.IncludeStrings).Add(includeString); + } + + return specificationBuilder; } - var orderedSpecificationBuilder = new OrderedSpecificationBuilder(specificationBuilder.Specification, !condition); - - return orderedSpecificationBuilder; - } - - /// - /// Specify an include expression. - /// This information is utilized to build Include function in the query, which ORM tools like Entity Framework use - /// to include related entities (via navigation properties) in the query result. - /// - /// - /// - /// - /// - public static IIncludableSpecificationBuilder Include( - this ISpecificationBuilder specificationBuilder, - Expression> includeExpression) where T : class - => Include(specificationBuilder, includeExpression, true); - - /// - /// Specify an include expression. - /// This information is utilized to build Include function in the query, which ORM tools like Entity Framework use - /// to include related entities (via navigation properties) in the query result. - /// - /// - /// - /// - /// - /// If false, the expression won't be added. The whole Include chain will be discarded. - public static IIncludableSpecificationBuilder Include( - this ISpecificationBuilder specificationBuilder, - Expression> includeExpression, - bool condition) where T : class - { - if (condition) + /// + /// Specify a 'SQL LIKE' operations for search purposes + /// + /// + /// + /// the property to apply the SQL LIKE against + /// the value to use for the SQL LIKE + /// the index used to group sets of Selectors and SearchTerms together + public static ISpecificationBuilder Search( + this ISpecificationBuilder specificationBuilder, + Expression> selector, + string searchTerm, + int searchGroup = 1) where T : class + => Search(specificationBuilder, selector, searchTerm, true, searchGroup); + + /// + /// Specify a 'SQL LIKE' operations for search purposes + /// + /// + /// + /// the property to apply the SQL LIKE against + /// the value to use for the SQL LIKE + /// If false, the expression won't be added. + /// the index used to group sets of Selectors and SearchTerms together + public static ISpecificationBuilder Search( + this ISpecificationBuilder specificationBuilder, + Expression> selector, + string searchTerm, + bool condition, + int searchGroup = 1) where T : class { - var info = new IncludeExpressionInfo(includeExpression, typeof(T), typeof(TProperty)); + if (condition) + { + ((List>)specificationBuilder.Specification.SearchCriterias).Add(new SearchExpressionInfo(selector, searchTerm, searchGroup)); + } - ((List)specificationBuilder.Specification.IncludeExpressions).Add(info); + return specificationBuilder; } - var includeBuilder = new IncludableSpecificationBuilder(specificationBuilder.Specification, !condition); - - return includeBuilder; - } - - /// - /// Specify a collection of navigation properties, as strings, to include in the query. - /// - /// - /// - /// - public static ISpecificationBuilder Include( - this ISpecificationBuilder specificationBuilder, - string includeString) where T : class - => Include(specificationBuilder, includeString, true); - - /// - /// Specify a collection of navigation properties, as strings, to include in the query. - /// - /// - /// - /// - /// If false, the include expression won't be added. - public static ISpecificationBuilder Include( - this ISpecificationBuilder specificationBuilder, - string includeString, - bool condition) where T : class - { - if (condition) + /// + /// Specify the number of elements to return. + /// + /// + /// number of elements to take + public static ISpecificationBuilder Take( + this ISpecificationBuilder specificationBuilder, + int take) + => Take(specificationBuilder, take, true); + + /// + /// Specify the number of elements to return. + /// + /// + /// number of elements to take + /// If false, the value will be discarded. + public static ISpecificationBuilder Take( + this ISpecificationBuilder specificationBuilder, + int take, + bool condition) { - ((List)specificationBuilder.Specification.IncludeStrings).Add(includeString); + if (condition) + { + if (specificationBuilder.Specification.Take != null) throw new DuplicateTakeException(); + + specificationBuilder.Specification.Take = take; + } + + return specificationBuilder; } - return specificationBuilder; - } - - /// - /// Specify a 'SQL LIKE' operations for search purposes - /// - /// - /// - /// the property to apply the SQL LIKE against - /// the value to use for the SQL LIKE - /// the index used to group sets of Selectors and SearchTerms together - public static ISpecificationBuilder Search( - this ISpecificationBuilder specificationBuilder, - Expression> selector, - string searchTerm, - int searchGroup = 1) where T : class - => Search(specificationBuilder, selector, searchTerm, true, searchGroup); - - /// - /// Specify a 'SQL LIKE' operations for search purposes - /// - /// - /// - /// the property to apply the SQL LIKE against - /// the value to use for the SQL LIKE - /// If false, the expression won't be added. - /// the index used to group sets of Selectors and SearchTerms together - public static ISpecificationBuilder Search( - this ISpecificationBuilder specificationBuilder, - Expression> selector, - string searchTerm, - bool condition, - int searchGroup = 1) where T : class - { - if (condition) + /// + /// Specify the number of elements to skip before returning the remaining elements. + /// + /// + /// + /// number of elements to skip + public static ISpecificationBuilder Skip( + this ISpecificationBuilder specificationBuilder, + int skip) + => Skip(specificationBuilder, skip, true); + + /// + /// Specify the number of elements to skip before returning the remaining elements. + /// + /// + /// + /// number of elements to skip + /// If false, the value will be discarded. + public static ISpecificationBuilder Skip( + this ISpecificationBuilder specificationBuilder, + int skip, + bool condition) { - ((List>)specificationBuilder.Specification.SearchCriterias).Add(new SearchExpressionInfo(selector, searchTerm, searchGroup)); + if (condition) + { + if (specificationBuilder.Specification.Skip != null) throw new DuplicateSkipException(); + + specificationBuilder.Specification.Skip = skip; + } + + return specificationBuilder; } - return specificationBuilder; - } - - /// - /// Specify the number of elements to return. - /// - /// - /// number of elements to take - public static ISpecificationBuilder Take( - this ISpecificationBuilder specificationBuilder, - int take) - => Take(specificationBuilder, take, true); - - /// - /// Specify the number of elements to return. - /// - /// - /// number of elements to take - /// If false, the value will be discarded. - public static ISpecificationBuilder Take( - this ISpecificationBuilder specificationBuilder, - int take, - bool condition) - { - if (condition) + /// + /// Specify a transform function to apply to the element + /// to produce another element. + /// + public static ISpecificationBuilder Select( + this ISpecificationBuilder specificationBuilder, + Expression> selector) { - if (specificationBuilder.Specification.Take != null) throw new DuplicateTakeException(); + specificationBuilder.Specification.Selector = selector; - specificationBuilder.Specification.Take = take; + return specificationBuilder; } - return specificationBuilder; - } - - /// - /// Specify the number of elements to skip before returning the remaining elements. - /// - /// - /// - /// number of elements to skip - public static ISpecificationBuilder Skip( - this ISpecificationBuilder specificationBuilder, - int skip) - => Skip(specificationBuilder, skip, true); - - /// - /// Specify the number of elements to skip before returning the remaining elements. - /// - /// - /// - /// number of elements to skip - /// If false, the value will be discarded. - public static ISpecificationBuilder Skip( - this ISpecificationBuilder specificationBuilder, - int skip, - bool condition) - { - if (condition) + /// + /// Specify a transform function to apply to the element + /// to produce a flattened sequence of elements. + /// + public static ISpecificationBuilder SelectMany( + this ISpecificationBuilder specificationBuilder, + Expression>> selector) { - if (specificationBuilder.Specification.Skip != null) throw new DuplicateSkipException(); + specificationBuilder.Specification.SelectorMany = selector; - specificationBuilder.Specification.Skip = skip; + return specificationBuilder; } - return specificationBuilder; - } - - /// - /// Specify a transform function to apply to the element - /// to produce another element. - /// - public static ISpecificationBuilder Select( - this ISpecificationBuilder specificationBuilder, - Expression> selector) - { - specificationBuilder.Specification.Selector = selector; - - return specificationBuilder; - } - - /// - /// Specify a transform function to apply to the element - /// to produce a flattened sequence of elements. - /// - public static ISpecificationBuilder SelectMany( - this ISpecificationBuilder specificationBuilder, - Expression>> selector) - { - specificationBuilder.Specification.SelectorMany = selector; - - return specificationBuilder; - } - - /// - /// Specify a transform function to apply to the result of the query - /// and returns the same type - /// - public static ISpecificationBuilder PostProcessingAction( - this ISpecificationBuilder specificationBuilder, - Func, IEnumerable> predicate) - { - specificationBuilder.Specification.PostProcessingAction = predicate; - - return specificationBuilder; - } - - /// - /// Specify a transform function to apply to the result of the query. - /// and returns another type - /// - public static ISpecificationBuilder PostProcessingAction( - this ISpecificationBuilder specificationBuilder, - Func, IEnumerable> predicate) - { - specificationBuilder.Specification.PostProcessingAction = predicate; - - return specificationBuilder; - } - - /// - /// Must be called after specifying criteria - /// - /// - /// Any arguments used in defining the specification - public static ICacheSpecificationBuilder EnableCache( - this ISpecificationBuilder specificationBuilder, - string specificationName, - params object[] args) where T : class - => EnableCache(specificationBuilder, specificationName, true, args); - - /// - /// Must be called after specifying criteria - /// - /// - /// Any arguments used in defining the specification - /// If false, the caching won't be enabled. - public static ICacheSpecificationBuilder EnableCache( - this ISpecificationBuilder specificationBuilder, - string specificationName, - bool condition, - params object[] args) where T : class - { - if (condition) + /// + /// Specify a transform function to apply to the result of the query + /// and returns the same type + /// + public static ISpecificationBuilder PostProcessingAction( + this ISpecificationBuilder specificationBuilder, + Func, IEnumerable> predicate) { - if (string.IsNullOrEmpty(specificationName)) - { - throw new ArgumentException($"Required input {specificationName} was null or empty.", specificationName); - } + specificationBuilder.Specification.PostProcessingAction = predicate; - specificationBuilder.Specification.CacheKey = $"{specificationName}-{string.Join("-", args)}"; + return specificationBuilder; + } + + /// + /// Specify a transform function to apply to the result of the query. + /// and returns another type + /// + public static ISpecificationBuilder PostProcessingAction( + this ISpecificationBuilder specificationBuilder, + Func, IEnumerable> predicate) + { + specificationBuilder.Specification.PostProcessingAction = predicate; - specificationBuilder.Specification.CacheEnabled = true; + return specificationBuilder; } - var cacheBuilder = new CacheSpecificationBuilder(specificationBuilder.Specification, !condition); - - return cacheBuilder; - } - - /// - /// If the entity instances are modified, this will be detected - /// by the change tracker. - /// - /// - public static ISpecificationBuilder AsTracking( - this ISpecificationBuilder specificationBuilder) where T : class - => AsTracking(specificationBuilder, true); - - /// - /// If the entity instances are modified, this will be detected - /// by the change tracker. - /// - /// - /// If false, the setting will be discarded. - public static ISpecificationBuilder AsTracking( - this ISpecificationBuilder specificationBuilder, - bool condition) where T : class - { - if (condition) + /// + /// Must be called after specifying criteria + /// + /// + /// Any arguments used in defining the specification + public static ICacheSpecificationBuilder EnableCache( + this ISpecificationBuilder specificationBuilder, + string specificationName, + params object[] args) where T : class + => EnableCache(specificationBuilder, specificationName, true, args); + + /// + /// Must be called after specifying criteria + /// + /// + /// Any arguments used in defining the specification + /// If false, the caching won't be enabled. + public static ICacheSpecificationBuilder EnableCache( + this ISpecificationBuilder specificationBuilder, + string specificationName, + bool condition, + params object[] args) where T : class { - specificationBuilder.Specification.AsNoTracking = false; - specificationBuilder.Specification.AsNoTrackingWithIdentityResolution = false; - specificationBuilder.Specification.AsTracking = true; + if (condition) + { + if (string.IsNullOrEmpty(specificationName)) + { + throw new ArgumentException($"Required input {specificationName} was null or empty.", specificationName); + } + + specificationBuilder.Specification.CacheKey = $"{specificationName}-{string.Join("-", args)}"; + + specificationBuilder.Specification.CacheEnabled = true; + } + + var cacheBuilder = new CacheSpecificationBuilder(specificationBuilder.Specification, !condition); + + return cacheBuilder; } - return specificationBuilder; - } - - /// - /// If the entity instances are modified, this will not be detected - /// by the change tracker. - /// - /// - public static ISpecificationBuilder AsNoTracking( - this ISpecificationBuilder specificationBuilder) where T : class - => AsNoTracking(specificationBuilder, true); - - /// - /// If the entity instances are modified, this will not be detected - /// by the change tracker. - /// - /// - /// If false, the setting will be discarded. - public static ISpecificationBuilder AsNoTracking( - this ISpecificationBuilder specificationBuilder, - bool condition) where T : class - { - if (condition) + /// + /// If the entity instances are modified, this will be detected + /// by the change tracker. + /// + /// + public static ISpecificationBuilder AsTracking( + this ISpecificationBuilder specificationBuilder) where T : class + => AsTracking(specificationBuilder, true); + + /// + /// If the entity instances are modified, this will be detected + /// by the change tracker. + /// + /// + /// If false, the setting will be discarded. + public static ISpecificationBuilder AsTracking( + this ISpecificationBuilder specificationBuilder, + bool condition) where T : class { - specificationBuilder.Specification.AsTracking = false; - specificationBuilder.Specification.AsNoTrackingWithIdentityResolution = false; - specificationBuilder.Specification.AsNoTracking = true; + if (condition) + { + specificationBuilder.Specification.AsNoTracking = false; + specificationBuilder.Specification.AsNoTrackingWithIdentityResolution = false; + specificationBuilder.Specification.AsTracking = true; + } + + return specificationBuilder; } - return specificationBuilder; - } - - /// - /// The generated sql query will be split into multiple SQL queries - /// - /// - /// This feature was introduced in EF Core 5.0. It only works when using Include - /// for more info: https://docs.microsoft.com/en-us/ef/core/querying/single-split-queries - /// - /// - /// - public static ISpecificationBuilder AsSplitQuery( - this ISpecificationBuilder specificationBuilder) where T : class - => AsSplitQuery(specificationBuilder, true); - - /// - /// The generated sql query will be split into multiple SQL queries - /// - /// - /// This feature was introduced in EF Core 5.0. It only works when using Include - /// for more info: https://docs.microsoft.com/en-us/ef/core/querying/single-split-queries - /// - /// - /// - /// If false, the setting will be discarded. - public static ISpecificationBuilder AsSplitQuery( - this ISpecificationBuilder specificationBuilder, - bool condition) where T : class - { - if (condition) + /// + /// If the entity instances are modified, this will not be detected + /// by the change tracker. + /// + /// + public static ISpecificationBuilder AsNoTracking( + this ISpecificationBuilder specificationBuilder) where T : class + => AsNoTracking(specificationBuilder, true); + + /// + /// If the entity instances are modified, this will not be detected + /// by the change tracker. + /// + /// + /// If false, the setting will be discarded. + public static ISpecificationBuilder AsNoTracking( + this ISpecificationBuilder specificationBuilder, + bool condition) where T : class { - specificationBuilder.Specification.AsSplitQuery = true; + if (condition) + { + specificationBuilder.Specification.AsTracking = false; + specificationBuilder.Specification.AsNoTrackingWithIdentityResolution = false; + specificationBuilder.Specification.AsNoTracking = true; + } + + return specificationBuilder; } - return specificationBuilder; - } - - /// - /// The query will then keep track of returned instances - /// (without tracking them in the normal way) - /// and ensure no duplicates are created in the query results - /// - /// - /// for more info: https://docs.microsoft.com/en-us/ef/core/change-tracking/identity-resolution#identity-resolution-and-queries - /// - /// - /// - public static ISpecificationBuilder AsNoTrackingWithIdentityResolution( - this ISpecificationBuilder specificationBuilder) where T : class - => AsNoTrackingWithIdentityResolution(specificationBuilder, true); - - /// - /// The query will then keep track of returned instances - /// (without tracking them in the normal way) - /// and ensure no duplicates are created in the query results - /// - /// - /// for more info: https://docs.microsoft.com/en-us/ef/core/change-tracking/identity-resolution#identity-resolution-and-queries - /// - /// - /// - /// If false, the setting will be discarded. - public static ISpecificationBuilder AsNoTrackingWithIdentityResolution( - this ISpecificationBuilder specificationBuilder, - bool condition) where T : class - { - if (condition) + /// + /// The generated sql query will be split into multiple SQL queries + /// + /// + /// This feature was introduced in EF Core 5.0. It only works when using Include + /// for more info: https://docs.microsoft.com/en-us/ef/core/querying/single-split-queries + /// + /// + /// + public static ISpecificationBuilder AsSplitQuery( + this ISpecificationBuilder specificationBuilder) where T : class + => AsSplitQuery(specificationBuilder, true); + + /// + /// The generated sql query will be split into multiple SQL queries + /// + /// + /// This feature was introduced in EF Core 5.0. It only works when using Include + /// for more info: https://docs.microsoft.com/en-us/ef/core/querying/single-split-queries + /// + /// + /// + /// If false, the setting will be discarded. + public static ISpecificationBuilder AsSplitQuery( + this ISpecificationBuilder specificationBuilder, + bool condition) where T : class { - specificationBuilder.Specification.AsTracking = false; - specificationBuilder.Specification.AsNoTracking = false; - specificationBuilder.Specification.AsNoTrackingWithIdentityResolution = true; + if (condition) + { + specificationBuilder.Specification.AsSplitQuery = true; + } + + return specificationBuilder; } - 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 - => IgnoreQueryFilters(specificationBuilder, true); - - /// - /// The query will ignore the defined global query filters - /// - /// - /// for more info: https://docs.microsoft.com/en-us/ef/core/querying/filters - /// - /// - /// - /// If false, the setting will be discarded. - public static ISpecificationBuilder IgnoreQueryFilters( - this ISpecificationBuilder specificationBuilder, - bool condition) where T : class - { - if (condition) + /// + /// The query will then keep track of returned instances + /// (without tracking them in the normal way) + /// and ensure no duplicates are created in the query results + /// + /// + /// for more info: https://docs.microsoft.com/en-us/ef/core/change-tracking/identity-resolution#identity-resolution-and-queries + /// + /// + /// + public static ISpecificationBuilder AsNoTrackingWithIdentityResolution( + this ISpecificationBuilder specificationBuilder) where T : class + => AsNoTrackingWithIdentityResolution(specificationBuilder, true); + + /// + /// The query will then keep track of returned instances + /// (without tracking them in the normal way) + /// and ensure no duplicates are created in the query results + /// + /// + /// for more info: https://docs.microsoft.com/en-us/ef/core/change-tracking/identity-resolution#identity-resolution-and-queries + /// + /// + /// + /// If false, the setting will be discarded. + public static ISpecificationBuilder AsNoTrackingWithIdentityResolution( + this ISpecificationBuilder specificationBuilder, + bool condition) where T : class { - specificationBuilder.Specification.IgnoreQueryFilters = true; + if (condition) + { + specificationBuilder.Specification.AsTracking = false; + specificationBuilder.Specification.AsNoTracking = false; + specificationBuilder.Specification.AsNoTrackingWithIdentityResolution = true; + } + + return specificationBuilder; } - 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 + => IgnoreQueryFilters(specificationBuilder, true); + + /// + /// The query will ignore the defined global query filters + /// + /// + /// for more info: https://docs.microsoft.com/en-us/ef/core/querying/filters + /// + /// + /// + /// If false, the setting will be discarded. + public static ISpecificationBuilder IgnoreQueryFilters( + this ISpecificationBuilder specificationBuilder, + bool condition) where T : class + { + if (condition) + { + specificationBuilder.Specification.IgnoreQueryFilters = true; + } + + return specificationBuilder; + } } diff --git a/Specification/src/Ardalis.Specification/Evaluators/IEvaluator.cs b/Specification/src/Ardalis.Specification/Evaluators/IEvaluator.cs index 0b05e55b..e4bd3571 100644 --- a/Specification/src/Ardalis.Specification/Evaluators/IEvaluator.cs +++ b/Specification/src/Ardalis.Specification/Evaluators/IEvaluator.cs @@ -4,7 +4,7 @@ namespace Ardalis.Specification; public interface IEvaluator { - bool IsCriteriaEvaluator { get; } + bool IsCriteriaEvaluator { get; } - IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class; + IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class; } diff --git a/Specification/src/Ardalis.Specification/Evaluators/IInMemoryEvaluator.cs b/Specification/src/Ardalis.Specification/Evaluators/IInMemoryEvaluator.cs index 082fa031..6e91cc2b 100644 --- a/Specification/src/Ardalis.Specification/Evaluators/IInMemoryEvaluator.cs +++ b/Specification/src/Ardalis.Specification/Evaluators/IInMemoryEvaluator.cs @@ -4,5 +4,5 @@ namespace Ardalis.Specification; public interface IInMemoryEvaluator { - IEnumerable Evaluate(IEnumerable query, ISpecification specification); + IEnumerable Evaluate(IEnumerable query, ISpecification specification); } diff --git a/Specification/src/Ardalis.Specification/Evaluators/IInMemorySpecificationEvaluator.cs b/Specification/src/Ardalis.Specification/Evaluators/IInMemorySpecificationEvaluator.cs index a941fb4b..648e244d 100644 --- a/Specification/src/Ardalis.Specification/Evaluators/IInMemorySpecificationEvaluator.cs +++ b/Specification/src/Ardalis.Specification/Evaluators/IInMemorySpecificationEvaluator.cs @@ -4,6 +4,6 @@ namespace Ardalis.Specification; public interface IInMemorySpecificationEvaluator { - IEnumerable Evaluate(IEnumerable source, ISpecification specification); - IEnumerable Evaluate(IEnumerable source, ISpecification specification); + IEnumerable Evaluate(IEnumerable source, ISpecification specification); + IEnumerable Evaluate(IEnumerable source, ISpecification specification); } diff --git a/Specification/src/Ardalis.Specification/Evaluators/ISpecificationEvaluator.cs b/Specification/src/Ardalis.Specification/Evaluators/ISpecificationEvaluator.cs index c4f08861..6c6bcbcd 100644 --- a/Specification/src/Ardalis.Specification/Evaluators/ISpecificationEvaluator.cs +++ b/Specification/src/Ardalis.Specification/Evaluators/ISpecificationEvaluator.cs @@ -7,20 +7,20 @@ namespace Ardalis.Specification; /// public interface ISpecificationEvaluator { - /// - /// Applies the logic encapsulated by to given , - /// and projects the result into . - /// - /// The type of the result. - /// The sequence of - /// The encapsulated query logic. - /// A filtered sequence of - IQueryable GetQuery(IQueryable inputQuery, ISpecification specification) where T : class; - /// - /// Applies the logic encapsulated by to given . - /// - /// The sequence of - /// The encapsulated query logic. - /// A filtered sequence of - IQueryable GetQuery(IQueryable inputQuery, ISpecification specification, bool evaluateCriteriaOnly = false) where T : class; + /// + /// Applies the logic encapsulated by to given , + /// and projects the result into . + /// + /// The type of the result. + /// The sequence of + /// The encapsulated query logic. + /// A filtered sequence of + IQueryable GetQuery(IQueryable inputQuery, ISpecification specification) where T : class; + /// + /// Applies the logic encapsulated by to given . + /// + /// The sequence of + /// The encapsulated query logic. + /// A filtered sequence of + IQueryable GetQuery(IQueryable inputQuery, ISpecification specification, bool evaluateCriteriaOnly = false) where T : class; } diff --git a/Specification/src/Ardalis.Specification/Evaluators/InMemorySpecificationEvaluator.cs b/Specification/src/Ardalis.Specification/Evaluators/InMemorySpecificationEvaluator.cs index fc893a68..efce6274 100644 --- a/Specification/src/Ardalis.Specification/Evaluators/InMemorySpecificationEvaluator.cs +++ b/Specification/src/Ardalis.Specification/Evaluators/InMemorySpecificationEvaluator.cs @@ -5,51 +5,51 @@ namespace Ardalis.Specification; public class InMemorySpecificationEvaluator : IInMemorySpecificationEvaluator { - // Will use singleton for default configuration. Yet, it can be instantiated if necessary, with default or provided evaluators. - public static InMemorySpecificationEvaluator Default { get; } = new InMemorySpecificationEvaluator(); + // Will use singleton for default configuration. Yet, it can be instantiated if necessary, with default or provided evaluators. + public static InMemorySpecificationEvaluator Default { get; } = new InMemorySpecificationEvaluator(); - protected List Evaluators { get; } = new List(); + protected List Evaluators { get; } = new List(); - public InMemorySpecificationEvaluator() - { - Evaluators.AddRange(new IInMemoryEvaluator[] + public InMemorySpecificationEvaluator() { - WhereEvaluator.Instance, - SearchEvaluator.Instance, - OrderEvaluator.Instance, - PaginationEvaluator.Instance - }); - } - public InMemorySpecificationEvaluator(IEnumerable evaluators) - { - Evaluators.AddRange(evaluators); - } - - public virtual IEnumerable Evaluate(IEnumerable source, ISpecification specification) - { - if (specification.Selector is null && specification.SelectorMany is null) throw new SelectorNotFoundException(); - if (specification.Selector != null && specification.SelectorMany != null) throw new ConcurrentSelectorsException(); - - var baseQuery = Evaluate(source, (ISpecification)specification); - - var resultQuery = specification.Selector != null - ? baseQuery.Select(specification.Selector.Compile()) - : baseQuery.SelectMany(specification.SelectorMany!.Compile()); - - return specification.PostProcessingAction == null - ? resultQuery - : specification.PostProcessingAction(resultQuery); - } - - public virtual IEnumerable Evaluate(IEnumerable source, ISpecification specification) - { - foreach (var evaluator in Evaluators) + Evaluators.AddRange(new IInMemoryEvaluator[] + { + WhereEvaluator.Instance, + SearchEvaluator.Instance, + OrderEvaluator.Instance, + PaginationEvaluator.Instance + }); + } + public InMemorySpecificationEvaluator(IEnumerable evaluators) { - source = evaluator.Evaluate(source, specification); + Evaluators.AddRange(evaluators); } - return specification.PostProcessingAction == null - ? source - : specification.PostProcessingAction(source); - } + public virtual IEnumerable Evaluate(IEnumerable source, ISpecification specification) + { + if (specification.Selector is null && specification.SelectorMany is null) throw new SelectorNotFoundException(); + if (specification.Selector != null && specification.SelectorMany != null) throw new ConcurrentSelectorsException(); + + var baseQuery = Evaluate(source, (ISpecification)specification); + + var resultQuery = specification.Selector != null + ? baseQuery.Select(specification.Selector.Compile()) + : baseQuery.SelectMany(specification.SelectorMany!.Compile()); + + return specification.PostProcessingAction == null + ? resultQuery + : specification.PostProcessingAction(resultQuery); + } + + public virtual IEnumerable Evaluate(IEnumerable source, ISpecification specification) + { + foreach (var evaluator in Evaluators) + { + source = evaluator.Evaluate(source, specification); + } + + return specification.PostProcessingAction == null + ? source + : specification.PostProcessingAction(source); + } } diff --git a/Specification/src/Ardalis.Specification/Evaluators/OrderEvaluator.cs b/Specification/src/Ardalis.Specification/Evaluators/OrderEvaluator.cs index 1d426d3f..ed0b3824 100644 --- a/Specification/src/Ardalis.Specification/Evaluators/OrderEvaluator.cs +++ b/Specification/src/Ardalis.Specification/Evaluators/OrderEvaluator.cs @@ -5,88 +5,88 @@ namespace Ardalis.Specification; public class OrderEvaluator : IEvaluator, IInMemoryEvaluator { - private OrderEvaluator() { } - public static OrderEvaluator Instance { get; } = new OrderEvaluator(); + private OrderEvaluator() { } + public static OrderEvaluator Instance { get; } = new OrderEvaluator(); - public bool IsCriteriaEvaluator { get; } = false; + public bool IsCriteriaEvaluator { get; } = false; - public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class - { - if (specification.OrderExpressions != null) + public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class { - if (specification.OrderExpressions.Count(x => x.OrderType == OrderTypeEnum.OrderBy - || x.OrderType == OrderTypeEnum.OrderByDescending) > 1) - { - throw new DuplicateOrderChainException(); - } - - IOrderedQueryable? orderedQuery = null; - foreach (var orderExpression in specification.OrderExpressions) - { - if (orderExpression.OrderType == OrderTypeEnum.OrderBy) - { - orderedQuery = query.OrderBy(orderExpression.KeySelector); - } - else if (orderExpression.OrderType == OrderTypeEnum.OrderByDescending) - { - orderedQuery = query.OrderByDescending(orderExpression.KeySelector); - } - else if (orderExpression.OrderType == OrderTypeEnum.ThenBy) + if (specification.OrderExpressions != null) { - orderedQuery = orderedQuery!.ThenBy(orderExpression.KeySelector); - } - else if (orderExpression.OrderType == OrderTypeEnum.ThenByDescending) - { - orderedQuery = orderedQuery!.ThenByDescending(orderExpression.KeySelector); + if (specification.OrderExpressions.Count(x => x.OrderType == OrderTypeEnum.OrderBy + || x.OrderType == OrderTypeEnum.OrderByDescending) > 1) + { + throw new DuplicateOrderChainException(); + } + + IOrderedQueryable? orderedQuery = null; + foreach (var orderExpression in specification.OrderExpressions) + { + if (orderExpression.OrderType == OrderTypeEnum.OrderBy) + { + orderedQuery = query.OrderBy(orderExpression.KeySelector); + } + else if (orderExpression.OrderType == OrderTypeEnum.OrderByDescending) + { + orderedQuery = query.OrderByDescending(orderExpression.KeySelector); + } + else if (orderExpression.OrderType == OrderTypeEnum.ThenBy) + { + orderedQuery = orderedQuery!.ThenBy(orderExpression.KeySelector); + } + else if (orderExpression.OrderType == OrderTypeEnum.ThenByDescending) + { + orderedQuery = orderedQuery!.ThenByDescending(orderExpression.KeySelector); + } + } + + if (orderedQuery != null) + { + query = orderedQuery; + } } - } - if (orderedQuery != null) - { - query = orderedQuery; - } + return query; } - return query; - } - - public IEnumerable Evaluate(IEnumerable query, ISpecification specification) - { - if (specification.OrderExpressions != null) + public IEnumerable Evaluate(IEnumerable query, ISpecification specification) { - if (specification.OrderExpressions.Count(x => x.OrderType == OrderTypeEnum.OrderBy - || x.OrderType == OrderTypeEnum.OrderByDescending) > 1) - { - throw new DuplicateOrderChainException(); - } - - IOrderedEnumerable? orderedQuery = null; - foreach (var orderExpression in specification.OrderExpressions) - { - if (orderExpression.OrderType == OrderTypeEnum.OrderBy) - { - orderedQuery = query.OrderBy(orderExpression.KeySelectorFunc); - } - else if (orderExpression.OrderType == OrderTypeEnum.OrderByDescending) - { - orderedQuery = query.OrderByDescending(orderExpression.KeySelectorFunc); - } - else if (orderExpression.OrderType == OrderTypeEnum.ThenBy) + if (specification.OrderExpressions != null) { - orderedQuery = orderedQuery!.ThenBy(orderExpression.KeySelectorFunc); - } - else if (orderExpression.OrderType == OrderTypeEnum.ThenByDescending) - { - orderedQuery = orderedQuery!.ThenByDescending(orderExpression.KeySelectorFunc); + if (specification.OrderExpressions.Count(x => x.OrderType == OrderTypeEnum.OrderBy + || x.OrderType == OrderTypeEnum.OrderByDescending) > 1) + { + throw new DuplicateOrderChainException(); + } + + IOrderedEnumerable? orderedQuery = null; + foreach (var orderExpression in specification.OrderExpressions) + { + if (orderExpression.OrderType == OrderTypeEnum.OrderBy) + { + orderedQuery = query.OrderBy(orderExpression.KeySelectorFunc); + } + else if (orderExpression.OrderType == OrderTypeEnum.OrderByDescending) + { + orderedQuery = query.OrderByDescending(orderExpression.KeySelectorFunc); + } + else if (orderExpression.OrderType == OrderTypeEnum.ThenBy) + { + orderedQuery = orderedQuery!.ThenBy(orderExpression.KeySelectorFunc); + } + else if (orderExpression.OrderType == OrderTypeEnum.ThenByDescending) + { + orderedQuery = orderedQuery!.ThenByDescending(orderExpression.KeySelectorFunc); + } + } + + if (orderedQuery != null) + { + query = orderedQuery; + } } - } - if (orderedQuery != null) - { - query = orderedQuery; - } + return query; } - - return query; - } } diff --git a/Specification/src/Ardalis.Specification/Evaluators/PaginationEvaluator.cs b/Specification/src/Ardalis.Specification/Evaluators/PaginationEvaluator.cs index 397207e9..f669024f 100644 --- a/Specification/src/Ardalis.Specification/Evaluators/PaginationEvaluator.cs +++ b/Specification/src/Ardalis.Specification/Evaluators/PaginationEvaluator.cs @@ -5,39 +5,39 @@ namespace Ardalis.Specification; public class PaginationEvaluator : IEvaluator, IInMemoryEvaluator { - private PaginationEvaluator() { } - public static PaginationEvaluator Instance { get; } = new PaginationEvaluator(); + private PaginationEvaluator() { } + public static PaginationEvaluator Instance { get; } = new PaginationEvaluator(); - public bool IsCriteriaEvaluator { get; } = false; + public bool IsCriteriaEvaluator { get; } = false; - public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class - { - // If skip is 0, avoid adding to the IQueryable. It will generate more optimized SQL that way. - if (specification.Skip != null && specification.Skip != 0) + public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class { - query = query.Skip(specification.Skip.Value); + // If skip is 0, avoid adding to the IQueryable. It will generate more optimized SQL that way. + if (specification.Skip != null && specification.Skip != 0) + { + query = query.Skip(specification.Skip.Value); + } + + if (specification.Take != null) + { + query = query.Take(specification.Take.Value); + } + + return query; } - if (specification.Take != null) + public IEnumerable Evaluate(IEnumerable query, ISpecification specification) { - query = query.Take(specification.Take.Value); - } - - return query; - } + if (specification.Skip != null && specification.Skip != 0) + { + query = query.Skip(specification.Skip.Value); + } - public IEnumerable Evaluate(IEnumerable query, ISpecification specification) - { - if (specification.Skip != null && specification.Skip != 0) - { - query = query.Skip(specification.Skip.Value); - } + if (specification.Take != null) + { + query = query.Take(specification.Take.Value); + } - if (specification.Take != null) - { - query = query.Take(specification.Take.Value); + return query; } - - return query; - } } diff --git a/Specification/src/Ardalis.Specification/Evaluators/SearchEvaluator.cs b/Specification/src/Ardalis.Specification/Evaluators/SearchEvaluator.cs index ece22642..0e029e8b 100644 --- a/Specification/src/Ardalis.Specification/Evaluators/SearchEvaluator.cs +++ b/Specification/src/Ardalis.Specification/Evaluators/SearchEvaluator.cs @@ -5,16 +5,16 @@ namespace Ardalis.Specification; public class SearchEvaluator : IInMemoryEvaluator { - private SearchEvaluator() { } - public static SearchEvaluator Instance { get; } = new SearchEvaluator(); + private SearchEvaluator() { } + public static SearchEvaluator Instance { get; } = new SearchEvaluator(); - public IEnumerable Evaluate(IEnumerable query, ISpecification specification) - { - foreach (var searchGroup in specification.SearchCriterias.GroupBy(x => x.SearchGroup)) + public IEnumerable Evaluate(IEnumerable query, ISpecification specification) { - query = query.Where(x => searchGroup.Any(c => c.SelectorFunc(x).Like(c.SearchTerm))); - } + foreach (var searchGroup in specification.SearchCriterias.GroupBy(x => x.SearchGroup)) + { + query = query.Where(x => searchGroup.Any(c => c.SelectorFunc(x).Like(c.SearchTerm))); + } - return query; - } + return query; + } } diff --git a/Specification/src/Ardalis.Specification/Evaluators/SearchExtension.cs b/Specification/src/Ardalis.Specification/Evaluators/SearchExtension.cs index 09706ecf..e6899e65 100644 --- a/Specification/src/Ardalis.Specification/Evaluators/SearchExtension.cs +++ b/Specification/src/Ardalis.Specification/Evaluators/SearchExtension.cs @@ -5,151 +5,151 @@ namespace Ardalis.Specification; public static class SearchExtension { - public static bool Like(this string input, string pattern) - { - try + public static bool Like(this string input, string pattern) { - return SqlLike(input, pattern); - } - catch (Exception) - { - throw new InvalidSearchPatternException(pattern); - } - } - - // This C# implementation of SQL Like operator is based on the following SO post https://stackoverflow.com/a/8583383/10577116 - // It covers almost all of the scenarios, and it's faster than regex based implementations. - // It may fail/throw in some very specific and edge cases, hence, wrap it in try/catch. - private static bool SqlLike(string str, string pattern) - { - var isMatch = true; - var isWildCardOn = false; - var isCharWildCardOn = false; - var isCharSetOn = false; - var isNotCharSetOn = false; - var lastWildCard = -1; - var patternIndex = 0; - var set = new List(); - var p = '\0'; - bool endOfPattern; - - for (var i = 0; i < str.Length; i++) - { - var c = str[i]; - endOfPattern = (patternIndex >= pattern.Length); - if (!endOfPattern) - { - p = pattern[patternIndex]; - - if (!isWildCardOn && p == '%') + try { - lastWildCard = patternIndex; - isWildCardOn = true; - while (patternIndex < pattern.Length && - pattern[patternIndex] == '%') - { - patternIndex++; - } - p = patternIndex >= pattern.Length ? '\0' : pattern[patternIndex]; + return SqlLike(input, pattern); } - else if (p == '_') + catch (Exception) { - isCharWildCardOn = true; - patternIndex++; + throw new InvalidSearchPatternException(pattern); } - else if (p == '[') - { - if (pattern[++patternIndex] == '^') - { - isNotCharSetOn = true; - patternIndex++; - } - else isCharSetOn = true; + } - set.Clear(); - if (pattern[patternIndex + 1] == '-' && pattern[patternIndex + 3] == ']') - { - var start = char.ToUpper(pattern[patternIndex]); - patternIndex += 2; - var end = char.ToUpper(pattern[patternIndex]); - if (start <= end) + // This C# implementation of SQL Like operator is based on the following SO post https://stackoverflow.com/a/8583383/10577116 + // It covers almost all of the scenarios, and it's faster than regex based implementations. + // It may fail/throw in some very specific and edge cases, hence, wrap it in try/catch. + private static bool SqlLike(string str, string pattern) + { + var isMatch = true; + var isWildCardOn = false; + var isCharWildCardOn = false; + var isCharSetOn = false; + var isNotCharSetOn = false; + var lastWildCard = -1; + var patternIndex = 0; + var set = new List(); + var p = '\0'; + bool endOfPattern; + + for (var i = 0; i < str.Length; i++) + { + var c = str[i]; + endOfPattern = (patternIndex >= pattern.Length); + if (!endOfPattern) { - for (var ci = start; ci <= end; ci++) - { - set.Add(ci); - } - } - patternIndex++; - } + p = pattern[patternIndex]; - while (patternIndex < pattern.Length && - pattern[patternIndex] != ']') - { - set.Add(pattern[patternIndex]); - patternIndex++; - } - patternIndex++; - } - } + if (!isWildCardOn && p == '%') + { + lastWildCard = patternIndex; + isWildCardOn = true; + while (patternIndex < pattern.Length && + pattern[patternIndex] == '%') + { + patternIndex++; + } + p = patternIndex >= pattern.Length ? '\0' : pattern[patternIndex]; + } + else if (p == '_') + { + isCharWildCardOn = true; + patternIndex++; + } + else if (p == '[') + { + if (pattern[++patternIndex] == '^') + { + isNotCharSetOn = true; + patternIndex++; + } + else isCharSetOn = true; - if (isWildCardOn) - { - if (char.ToUpper(c) == char.ToUpper(p)) - { - isWildCardOn = false; - patternIndex++; - } - } - else if (isCharWildCardOn) - { - isCharWildCardOn = false; - } - else if (isCharSetOn || isNotCharSetOn) - { - var charMatch = (set.Contains(char.ToUpper(c))); - if ((isNotCharSetOn && charMatch) || (isCharSetOn && !charMatch)) - { - if (lastWildCard >= 0) patternIndex = lastWildCard; - else - { - isMatch = false; - break; - } - } - isNotCharSetOn = isCharSetOn = false; - } - else - { - if (char.ToUpper(c) == char.ToUpper(p)) - { - patternIndex++; - } - else - { - if (lastWildCard >= 0) patternIndex = lastWildCard; - else - { - isMatch = false; - break; - } + set.Clear(); + if (pattern[patternIndex + 1] == '-' && pattern[patternIndex + 3] == ']') + { + var start = char.ToUpper(pattern[patternIndex]); + patternIndex += 2; + var end = char.ToUpper(pattern[patternIndex]); + if (start <= end) + { + for (var ci = start; ci <= end; ci++) + { + set.Add(ci); + } + } + patternIndex++; + } + + while (patternIndex < pattern.Length && + pattern[patternIndex] != ']') + { + set.Add(pattern[patternIndex]); + patternIndex++; + } + patternIndex++; + } + } + + if (isWildCardOn) + { + if (char.ToUpper(c) == char.ToUpper(p)) + { + isWildCardOn = false; + patternIndex++; + } + } + else if (isCharWildCardOn) + { + isCharWildCardOn = false; + } + else if (isCharSetOn || isNotCharSetOn) + { + var charMatch = (set.Contains(char.ToUpper(c))); + if ((isNotCharSetOn && charMatch) || (isCharSetOn && !charMatch)) + { + if (lastWildCard >= 0) patternIndex = lastWildCard; + else + { + isMatch = false; + break; + } + } + isNotCharSetOn = isCharSetOn = false; + } + else + { + if (char.ToUpper(c) == char.ToUpper(p)) + { + patternIndex++; + } + else + { + if (lastWildCard >= 0) patternIndex = lastWildCard; + else + { + isMatch = false; + break; + } + } + } } - } - } - endOfPattern = (patternIndex >= pattern.Length); + endOfPattern = (patternIndex >= pattern.Length); - if (isMatch && !endOfPattern) - { - var isOnlyWildCards = true; - for (var i = patternIndex; i < pattern.Length; i++) - { - if (pattern[i] != '%') + if (isMatch && !endOfPattern) { - isOnlyWildCards = false; - break; + var isOnlyWildCards = true; + for (var i = patternIndex; i < pattern.Length; i++) + { + if (pattern[i] != '%') + { + isOnlyWildCards = false; + break; + } + } + if (isOnlyWildCards) endOfPattern = true; } - } - if (isOnlyWildCards) endOfPattern = true; + return isMatch && endOfPattern; } - return isMatch && endOfPattern; - } } diff --git a/Specification/src/Ardalis.Specification/Evaluators/WhereEvaluator.cs b/Specification/src/Ardalis.Specification/Evaluators/WhereEvaluator.cs index 33d1907a..f64b17a8 100644 --- a/Specification/src/Ardalis.Specification/Evaluators/WhereEvaluator.cs +++ b/Specification/src/Ardalis.Specification/Evaluators/WhereEvaluator.cs @@ -5,28 +5,28 @@ namespace Ardalis.Specification; public class WhereEvaluator : IEvaluator, IInMemoryEvaluator { - private WhereEvaluator() { } - public static WhereEvaluator Instance { get; } = new WhereEvaluator(); + private WhereEvaluator() { } + public static WhereEvaluator Instance { get; } = new WhereEvaluator(); - public bool IsCriteriaEvaluator { get; } = true; + public bool IsCriteriaEvaluator { get; } = true; - public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class - { - foreach (var info in specification.WhereExpressions) + public IQueryable GetQuery(IQueryable query, ISpecification specification) where T : class { - query = query.Where(info.Filter); - } + foreach (var info in specification.WhereExpressions) + { + query = query.Where(info.Filter); + } - return query; - } + return query; + } - public IEnumerable Evaluate(IEnumerable query, ISpecification specification) - { - foreach (var info in specification.WhereExpressions) + public IEnumerable Evaluate(IEnumerable query, ISpecification specification) { - query = query.Where(info.FilterFunc); - } + foreach (var info in specification.WhereExpressions) + { + query = query.Where(info.FilterFunc); + } - return query; - } + return query; + } } diff --git a/Specification/src/Ardalis.Specification/Exceptions/ConcurrentSelectorsException.cs b/Specification/src/Ardalis.Specification/Exceptions/ConcurrentSelectorsException.cs index e6d3a134..4ea7c4e2 100644 --- a/Specification/src/Ardalis.Specification/Exceptions/ConcurrentSelectorsException.cs +++ b/Specification/src/Ardalis.Specification/Exceptions/ConcurrentSelectorsException.cs @@ -4,15 +4,15 @@ namespace Ardalis.Specification; public class ConcurrentSelectorsException : Exception { - private const string _message = "Concurrent specification selector transforms defined. Ensure only one of the Select() or SelectMany() transforms is used in the same specification!"; + private const string _message = "Concurrent specification selector transforms defined. Ensure only one of the Select() or SelectMany() transforms is used in the same specification!"; - public ConcurrentSelectorsException() - : base(_message) - { - } + public ConcurrentSelectorsException() + : base(_message) + { + } - public ConcurrentSelectorsException(Exception innerException) - : base(_message, innerException) - { - } + public ConcurrentSelectorsException(Exception innerException) + : base(_message, innerException) + { + } } diff --git a/Specification/src/Ardalis.Specification/Exceptions/DuplicateOrderChainException.cs b/Specification/src/Ardalis.Specification/Exceptions/DuplicateOrderChainException.cs index e9887d12..98a98c70 100644 --- a/Specification/src/Ardalis.Specification/Exceptions/DuplicateOrderChainException.cs +++ b/Specification/src/Ardalis.Specification/Exceptions/DuplicateOrderChainException.cs @@ -4,15 +4,15 @@ namespace Ardalis.Specification; public class DuplicateOrderChainException : Exception { - private const string _message = "The specification contains more than one Order chain!"; + private const string _message = "The specification contains more than one Order chain!"; - public DuplicateOrderChainException() - : base(_message) - { - } + public DuplicateOrderChainException() + : base(_message) + { + } - public DuplicateOrderChainException(Exception innerException) - : base(_message, innerException) - { - } + public DuplicateOrderChainException(Exception innerException) + : base(_message, innerException) + { + } } diff --git a/Specification/src/Ardalis.Specification/Exceptions/DuplicateSkipException.cs b/Specification/src/Ardalis.Specification/Exceptions/DuplicateSkipException.cs index 082f9d31..114da8c0 100644 --- a/Specification/src/Ardalis.Specification/Exceptions/DuplicateSkipException.cs +++ b/Specification/src/Ardalis.Specification/Exceptions/DuplicateSkipException.cs @@ -4,15 +4,15 @@ namespace Ardalis.Specification; public class DuplicateSkipException : Exception { - private const string _message = "Duplicate use of Skip(). Ensure you don't use Skip() more than once in the same specification!"; + private const string _message = "Duplicate use of Skip(). Ensure you don't use Skip() more than once in the same specification!"; - public DuplicateSkipException() - : base(_message) - { - } + public DuplicateSkipException() + : base(_message) + { + } - public DuplicateSkipException(Exception innerException) - : base(_message, innerException) - { - } + public DuplicateSkipException(Exception innerException) + : base(_message, innerException) + { + } } diff --git a/Specification/src/Ardalis.Specification/Exceptions/DuplicateTakeException.cs b/Specification/src/Ardalis.Specification/Exceptions/DuplicateTakeException.cs index 6c1ec900..31c751d2 100644 --- a/Specification/src/Ardalis.Specification/Exceptions/DuplicateTakeException.cs +++ b/Specification/src/Ardalis.Specification/Exceptions/DuplicateTakeException.cs @@ -4,15 +4,15 @@ namespace Ardalis.Specification; public class DuplicateTakeException : Exception { - private const string _message = "Duplicate use of Take(). Ensure you don't use Take() more than once in the same specification!"; + private const string _message = "Duplicate use of Take(). Ensure you don't use Take() more than once in the same specification!"; - public DuplicateTakeException() - : base(_message) - { - } + public DuplicateTakeException() + : base(_message) + { + } - public DuplicateTakeException(Exception innerException) - : base(_message, innerException) - { - } + public DuplicateTakeException(Exception innerException) + : base(_message, innerException) + { + } } diff --git a/Specification/src/Ardalis.Specification/Exceptions/InvalidSearchPatternException.cs b/Specification/src/Ardalis.Specification/Exceptions/InvalidSearchPatternException.cs index 3a047898..1bde3b0c 100644 --- a/Specification/src/Ardalis.Specification/Exceptions/InvalidSearchPatternException.cs +++ b/Specification/src/Ardalis.Specification/Exceptions/InvalidSearchPatternException.cs @@ -4,15 +4,15 @@ namespace Ardalis.Specification; public class InvalidSearchPatternException : Exception { - private const string _message = "Invalid search pattern: "; + private const string _message = "Invalid search pattern: "; - public InvalidSearchPatternException(string searchPattern) - : base($"{_message}{searchPattern}") - { - } + public InvalidSearchPatternException(string searchPattern) + : base($"{_message}{searchPattern}") + { + } - public InvalidSearchPatternException(string searchPattern, Exception innerException) - : base($"{_message}{searchPattern}", innerException) - { - } + public InvalidSearchPatternException(string searchPattern, Exception innerException) + : base($"{_message}{searchPattern}", innerException) + { + } } diff --git a/Specification/src/Ardalis.Specification/Exceptions/SelectorNotFoundException.cs b/Specification/src/Ardalis.Specification/Exceptions/SelectorNotFoundException.cs index b011a239..df01a31a 100644 --- a/Specification/src/Ardalis.Specification/Exceptions/SelectorNotFoundException.cs +++ b/Specification/src/Ardalis.Specification/Exceptions/SelectorNotFoundException.cs @@ -4,15 +4,15 @@ namespace Ardalis.Specification; public class SelectorNotFoundException : Exception { - private const string _message = "The specification must have a selector transform defined. Ensure either Select() or SelectMany() is used in the specification!"; + private const string _message = "The specification must have a selector transform defined. Ensure either Select() or SelectMany() is used in the specification!"; - public SelectorNotFoundException() - : base(_message) - { - } + public SelectorNotFoundException() + : base(_message) + { + } - public SelectorNotFoundException(Exception innerException) - : base(_message, innerException) - { - } + public SelectorNotFoundException(Exception innerException) + : base(_message, innerException) + { + } } diff --git a/Specification/src/Ardalis.Specification/Expressions/IncludeExpressionInfo.cs b/Specification/src/Ardalis.Specification/Expressions/IncludeExpressionInfo.cs index 8e4097ee..e119afcf 100644 --- a/Specification/src/Ardalis.Specification/Expressions/IncludeExpressionInfo.cs +++ b/Specification/src/Ardalis.Specification/Expressions/IncludeExpressionInfo.cs @@ -8,82 +8,82 @@ namespace Ardalis.Specification; /// public class IncludeExpressionInfo { - /// - /// If is , represents a related entity that should be included. - /// If is , represents a related entity that should be included as part of the previously included entity. - /// - public LambdaExpression LambdaExpression { get; } + /// + /// If is , represents a related entity that should be included. + /// If is , represents a related entity that should be included as part of the previously included entity. + /// + public LambdaExpression LambdaExpression { get; } - /// - /// The type of the source entity. - /// - public Type EntityType { get; } + /// + /// The type of the source entity. + /// + public Type EntityType { get; } - /// - /// The type of the included entity. - /// - public Type PropertyType { get; } + /// + /// The type of the included entity. + /// + public Type PropertyType { get; } - /// - /// The type of the previously included entity. - /// - public Type? PreviousPropertyType { get; } + /// + /// The type of the previously included entity. + /// + public Type? PreviousPropertyType { get; } - /// - /// The include type. - /// - public IncludeTypeEnum Type { get; } + /// + /// The include type. + /// + public IncludeTypeEnum Type { get; } - private IncludeExpressionInfo(LambdaExpression expression, - Type entityType, - Type propertyType, - Type? previousPropertyType, - IncludeTypeEnum includeType) + private IncludeExpressionInfo(LambdaExpression expression, + Type entityType, + Type propertyType, + Type? previousPropertyType, + IncludeTypeEnum includeType) - { - _ = expression ?? throw new ArgumentNullException(nameof(expression)); - _ = entityType ?? throw new ArgumentNullException(nameof(entityType)); - _ = propertyType ?? throw new ArgumentNullException(nameof(propertyType)); - - if (includeType == IncludeTypeEnum.ThenInclude) { - _ = previousPropertyType ?? throw new ArgumentNullException(nameof(previousPropertyType)); - } + _ = expression ?? throw new ArgumentNullException(nameof(expression)); + _ = entityType ?? throw new ArgumentNullException(nameof(entityType)); + _ = propertyType ?? throw new ArgumentNullException(nameof(propertyType)); - LambdaExpression = expression; - EntityType = entityType; - PropertyType = propertyType; - PreviousPropertyType = previousPropertyType; - Type = includeType; - } + if (includeType == IncludeTypeEnum.ThenInclude) + { + _ = previousPropertyType ?? throw new ArgumentNullException(nameof(previousPropertyType)); + } + + LambdaExpression = expression; + EntityType = entityType; + PropertyType = propertyType; + PreviousPropertyType = previousPropertyType; + Type = includeType; + } - /// - /// Creates instance of which describes 'Include' query part. - /// Source (entityType) -> Include (propertyType). - /// - /// The expression represents a related entity that should be included. - /// The type of the source entity. - /// The type of the included entity. - public IncludeExpressionInfo(LambdaExpression expression, - Type entityType, - Type propertyType) - : this(expression, entityType, propertyType, null, IncludeTypeEnum.Include) - { - } + /// + /// Creates instance of which describes 'Include' query part. + /// Source (entityType) -> Include (propertyType). + /// + /// The expression represents a related entity that should be included. + /// The type of the source entity. + /// The type of the included entity. + public IncludeExpressionInfo(LambdaExpression expression, + Type entityType, + Type propertyType) + : this(expression, entityType, propertyType, null, IncludeTypeEnum.Include) + { + } - /// - /// Creates instance of which describes 'ThenInclude' query part. - /// Source (entityType) -> Include (previousPropertyType) -> ThenInclude (propertyType). - /// - /// The expression represents a related entity that should be included as part of the previously included entity. - /// The type of the source entity. - /// The type of the included entity. - /// The type of the previously included entity. - public IncludeExpressionInfo(LambdaExpression expression, - Type entityType, - Type propertyType, - Type previousPropertyType) - : this(expression, entityType, propertyType, previousPropertyType, IncludeTypeEnum.ThenInclude) - { - } + /// + /// Creates instance of which describes 'ThenInclude' query part. + /// Source (entityType) -> Include (previousPropertyType) -> ThenInclude (propertyType). + /// + /// The expression represents a related entity that should be included as part of the previously included entity. + /// The type of the source entity. + /// The type of the included entity. + /// The type of the previously included entity. + public IncludeExpressionInfo(LambdaExpression expression, + Type entityType, + Type propertyType, + Type previousPropertyType) + : this(expression, entityType, propertyType, previousPropertyType, IncludeTypeEnum.ThenInclude) + { + } } diff --git a/Specification/src/Ardalis.Specification/Expressions/OrderExpressionInfo.cs b/Specification/src/Ardalis.Specification/Expressions/OrderExpressionInfo.cs index be98070e..5055182f 100644 --- a/Specification/src/Ardalis.Specification/Expressions/OrderExpressionInfo.cs +++ b/Specification/src/Ardalis.Specification/Expressions/OrderExpressionInfo.cs @@ -9,36 +9,36 @@ namespace Ardalis.Specification; /// Type of the entity to apply sort on. public class OrderExpressionInfo { - private readonly Lazy> _keySelectorFunc; - - /// - /// Creates instance of . - /// - /// A function to extract a key from an element. - /// Whether to (subsequently) sort ascending or descending. - /// If is null. - public OrderExpressionInfo(Expression> keySelector, OrderTypeEnum orderType) - { - _ = keySelector ?? throw new ArgumentNullException(nameof(keySelector)); - - KeySelector = keySelector; - OrderType = orderType; - - _keySelectorFunc = new Lazy>(KeySelector.Compile); - } - - /// - /// A function to extract a key from an element. - /// - public Expression> KeySelector { get; } - - /// - /// Whether to (subsequently) sort ascending or descending. - /// - public OrderTypeEnum OrderType { get; } - - /// - /// Compiled . - /// - public Func KeySelectorFunc => _keySelectorFunc.Value; + private readonly Lazy> _keySelectorFunc; + + /// + /// Creates instance of . + /// + /// A function to extract a key from an element. + /// Whether to (subsequently) sort ascending or descending. + /// If is null. + public OrderExpressionInfo(Expression> keySelector, OrderTypeEnum orderType) + { + _ = keySelector ?? throw new ArgumentNullException(nameof(keySelector)); + + KeySelector = keySelector; + OrderType = orderType; + + _keySelectorFunc = new Lazy>(KeySelector.Compile); + } + + /// + /// A function to extract a key from an element. + /// + public Expression> KeySelector { get; } + + /// + /// Whether to (subsequently) sort ascending or descending. + /// + public OrderTypeEnum OrderType { get; } + + /// + /// Compiled . + /// + public Func KeySelectorFunc => _keySelectorFunc.Value; } diff --git a/Specification/src/Ardalis.Specification/Expressions/SearchExpressionInfo.cs b/Specification/src/Ardalis.Specification/Expressions/SearchExpressionInfo.cs index e785dd35..d7231503 100644 --- a/Specification/src/Ardalis.Specification/Expressions/SearchExpressionInfo.cs +++ b/Specification/src/Ardalis.Specification/Expressions/SearchExpressionInfo.cs @@ -9,45 +9,45 @@ namespace Ardalis.Specification; /// Type of the source from which search target should be selected. public class SearchExpressionInfo { - private readonly Lazy> _selectorFunc; - - /// - /// Creates instance of . - /// - /// The property to apply the SQL LIKE against. - /// The value to use for the SQL LIKE. - /// The index used to group sets of Selectors and SearchTerms together. - /// If is null. - /// If is null or empty. - public SearchExpressionInfo(Expression> selector, string searchTerm, int searchGroup = 1) - { - _ = selector ?? throw new ArgumentNullException(nameof(selector)); - if (string.IsNullOrEmpty(searchTerm)) throw new ArgumentException("The search term can not be null or empty."); - - Selector = selector; - SearchTerm = searchTerm; - SearchGroup = searchGroup; - - _selectorFunc = new Lazy>(Selector.Compile); - } - - /// - /// The property to apply the SQL LIKE against. - /// - public Expression> Selector { get; } - - /// - /// The value to use for the SQL LIKE. - /// - public string SearchTerm { get; } - - /// - /// The index used to group sets of Selectors and SearchTerms together. - /// - public int SearchGroup { get; } - - /// - /// Compiled . - /// - public Func SelectorFunc => _selectorFunc.Value; + private readonly Lazy> _selectorFunc; + + /// + /// Creates instance of . + /// + /// The property to apply the SQL LIKE against. + /// The value to use for the SQL LIKE. + /// The index used to group sets of Selectors and SearchTerms together. + /// If is null. + /// If is null or empty. + public SearchExpressionInfo(Expression> selector, string searchTerm, int searchGroup = 1) + { + _ = selector ?? throw new ArgumentNullException(nameof(selector)); + if (string.IsNullOrEmpty(searchTerm)) throw new ArgumentException("The search term can not be null or empty."); + + Selector = selector; + SearchTerm = searchTerm; + SearchGroup = searchGroup; + + _selectorFunc = new Lazy>(Selector.Compile); + } + + /// + /// The property to apply the SQL LIKE against. + /// + public Expression> Selector { get; } + + /// + /// The value to use for the SQL LIKE. + /// + public string SearchTerm { get; } + + /// + /// The index used to group sets of Selectors and SearchTerms together. + /// + public int SearchGroup { get; } + + /// + /// Compiled . + /// + public Func SelectorFunc => _selectorFunc.Value; } diff --git a/Specification/src/Ardalis.Specification/Expressions/WhereExpressionInfo.cs b/Specification/src/Ardalis.Specification/Expressions/WhereExpressionInfo.cs index 2680f9a7..1291315d 100644 --- a/Specification/src/Ardalis.Specification/Expressions/WhereExpressionInfo.cs +++ b/Specification/src/Ardalis.Specification/Expressions/WhereExpressionInfo.cs @@ -9,29 +9,29 @@ namespace Ardalis.Specification; /// Type of the entity to apply filter on. public class WhereExpressionInfo { - private readonly Lazy> _filterFunc; + private readonly Lazy> _filterFunc; - /// - /// Creates instance of . - /// - /// Condition which should be satisfied by instances of . - /// If is null. - public WhereExpressionInfo(Expression> filter) - { - _ = filter ?? throw new ArgumentNullException(nameof(filter)); + /// + /// Creates instance of . + /// + /// Condition which should be satisfied by instances of . + /// If is null. + public WhereExpressionInfo(Expression> filter) + { + _ = filter ?? throw new ArgumentNullException(nameof(filter)); - Filter = filter; + Filter = filter; - _filterFunc = new Lazy>(Filter.Compile); - } + _filterFunc = new Lazy>(Filter.Compile); + } - /// - /// Condition which should be satisfied by instances of . - /// - public Expression> Filter { get; } + /// + /// Condition which should be satisfied by instances of . + /// + public Expression> Filter { get; } - /// - /// Compiled . - /// - public Func FilterFunc => _filterFunc.Value; + /// + /// Compiled . + /// + public Func FilterFunc => _filterFunc.Value; } diff --git a/Specification/src/Ardalis.Specification/IEntity.cs b/Specification/src/Ardalis.Specification/IEntity.cs index 831b2e4b..464d6291 100644 --- a/Specification/src/Ardalis.Specification/IEntity.cs +++ b/Specification/src/Ardalis.Specification/IEntity.cs @@ -2,5 +2,5 @@ public interface IEntity { - TId Id { get; set; } + TId Id { get; set; } } diff --git a/Specification/src/Ardalis.Specification/IReadRepositoryBase.cs b/Specification/src/Ardalis.Specification/IReadRepositoryBase.cs index 314370bc..89ea8e8a 100644 --- a/Specification/src/Ardalis.Specification/IReadRepositoryBase.cs +++ b/Specification/src/Ardalis.Specification/IReadRepositoryBase.cs @@ -14,170 +14,170 @@ namespace Ardalis.Specification; /// The type of entity being operated on by this repository. public interface IReadRepositoryBase where T : class { - /// - /// Finds an entity with the given primary key value. - /// - /// The type of primary key. - /// The value of the primary key for the entity to be found. - /// - /// - /// A task that represents the asynchronous operation. - /// The task result contains the , or . - /// - Task GetByIdAsync(TId id, CancellationToken cancellationToken = default) where TId : notnull; - - /// - /// Finds an entity that matches the encapsulated query logic of the . - /// - /// The encapsulated query logic. - /// - /// A task that represents the asynchronous operation. - /// The task result contains the , or . - /// - [Obsolete] - Task GetBySpecAsync(ISpecification specification, CancellationToken cancellationToken = default); - - /// - /// Finds an entity that matches the encapsulated query logic of the . - /// - /// The type of the result. - /// The encapsulated query logic. - /// - /// A task that represents the asynchronous operation. - /// The task result contains the . - /// - [Obsolete] - Task GetBySpecAsync(ISpecification specification, CancellationToken cancellationToken = default); - - /// - /// Returns the first element of a sequence, or a default value if the sequence contains no elements. - /// - /// The encapsulated query logic. - /// A to observe while waiting for the task to complete. - /// - /// A task that represents the asynchronous operation. - /// The task result contains the , or . - /// - Task FirstOrDefaultAsync(ISpecification specification, CancellationToken cancellationToken = default); - - /// - /// Returns the first element of a sequence, or a default value if the sequence contains no elements. - /// - /// The encapsulated query logic. - /// A to observe while waiting for the task to complete. - /// - /// A task that represents the asynchronous operation. - /// The task result contains the , or . - /// - Task FirstOrDefaultAsync(ISpecification specification, CancellationToken cancellationToken = default); - - /// - /// Returns the only element of a sequence, or a default value if the sequence is empty; this method throws an exception if there is more than one element in the sequence. - /// - /// The encapsulated query logic. - /// A to observe while waiting for the task to complete. - /// - /// A task that represents the asynchronous operation. - /// The task result contains the , or . - /// - Task SingleOrDefaultAsync(ISingleResultSpecification specification, CancellationToken cancellationToken = default); - - /// - /// Returns the only element of a sequence, or a default value if the sequence is empty; this method throws an exception if there is more than one element in the sequence. - /// - /// The encapsulated query logic. - /// A to observe while waiting for the task to complete. - /// - /// A task that represents the asynchronous operation. - /// The task result contains the , or . - /// - Task SingleOrDefaultAsync(ISingleResultSpecification specification, CancellationToken cancellationToken = default); - - /// - /// Finds all entities of from the database. - /// - /// - /// A task that represents the asynchronous operation. - /// The task result contains a that contains elements from the input sequence. - /// - Task> ListAsync(CancellationToken cancellationToken = default); - - /// - /// Finds all entities of , that matches the encapsulated query logic of the - /// , from the database. - /// - /// The encapsulated query logic. - /// - /// A task that represents the asynchronous operation. - /// The task result contains a that contains elements from the input sequence. - /// - Task> ListAsync(ISpecification specification, CancellationToken cancellationToken = default); - - /// - /// Finds all entities of , that matches the encapsulated query logic of the - /// , from the database. - /// - /// Projects each entity into a new form, being . - /// - /// - /// The type of the value returned by the projection. - /// The encapsulated query logic. - /// - /// A task that represents the asynchronous operation. - /// The task result contains a that contains elements from the input sequence. - /// - Task> ListAsync(ISpecification specification, CancellationToken cancellationToken = default); - - /// - /// Returns a number that represents how many entities satisfy the encapsulated query logic - /// of the . - /// - /// The encapsulated query logic. - /// - /// A task that represents the asynchronous operation. The task result contains the - /// number of elements in the input sequence. - /// - Task CountAsync(ISpecification specification, CancellationToken cancellationToken = default); - - /// - /// Returns the total number of records. - /// - /// - /// A task that represents the asynchronous operation. The task result contains the - /// number of elements in the input sequence. - /// - Task CountAsync(CancellationToken cancellationToken = default); - - /// - /// Returns a boolean that represents whether any entity satisfy the encapsulated query logic - /// of the or not. - /// - /// The encapsulated query logic. - /// - /// A task that represents the asynchronous operation. The task result contains true if the - /// source sequence contains any elements; otherwise, false. - /// - Task AnyAsync(ISpecification specification, CancellationToken cancellationToken = default); - - /// - /// Returns a boolean whether any entity exists or not. - /// - /// - /// A task that represents the asynchronous operation. The task result contains true if the - /// source sequence contains any elements; otherwise, false. - /// - Task AnyAsync(CancellationToken cancellationToken = default); + /// + /// Finds an entity with the given primary key value. + /// + /// The type of primary key. + /// The value of the primary key for the entity to be found. + /// + /// + /// A task that represents the asynchronous operation. + /// The task result contains the , or . + /// + Task GetByIdAsync(TId id, CancellationToken cancellationToken = default) where TId : notnull; + + /// + /// Finds an entity that matches the encapsulated query logic of the . + /// + /// The encapsulated query logic. + /// + /// A task that represents the asynchronous operation. + /// The task result contains the , or . + /// + [Obsolete] + Task GetBySpecAsync(ISpecification specification, CancellationToken cancellationToken = default); + + /// + /// Finds an entity that matches the encapsulated query logic of the . + /// + /// The type of the result. + /// The encapsulated query logic. + /// + /// A task that represents the asynchronous operation. + /// The task result contains the . + /// + [Obsolete] + Task GetBySpecAsync(ISpecification specification, CancellationToken cancellationToken = default); + + /// + /// Returns the first element of a sequence, or a default value if the sequence contains no elements. + /// + /// The encapsulated query logic. + /// A to observe while waiting for the task to complete. + /// + /// A task that represents the asynchronous operation. + /// The task result contains the , or . + /// + Task FirstOrDefaultAsync(ISpecification specification, CancellationToken cancellationToken = default); + + /// + /// Returns the first element of a sequence, or a default value if the sequence contains no elements. + /// + /// The encapsulated query logic. + /// A to observe while waiting for the task to complete. + /// + /// A task that represents the asynchronous operation. + /// The task result contains the , or . + /// + Task FirstOrDefaultAsync(ISpecification specification, CancellationToken cancellationToken = default); + + /// + /// Returns the only element of a sequence, or a default value if the sequence is empty; this method throws an exception if there is more than one element in the sequence. + /// + /// The encapsulated query logic. + /// A to observe while waiting for the task to complete. + /// + /// A task that represents the asynchronous operation. + /// The task result contains the , or . + /// + Task SingleOrDefaultAsync(ISingleResultSpecification specification, CancellationToken cancellationToken = default); + + /// + /// Returns the only element of a sequence, or a default value if the sequence is empty; this method throws an exception if there is more than one element in the sequence. + /// + /// The encapsulated query logic. + /// A to observe while waiting for the task to complete. + /// + /// A task that represents the asynchronous operation. + /// The task result contains the , or . + /// + Task SingleOrDefaultAsync(ISingleResultSpecification specification, CancellationToken cancellationToken = default); + + /// + /// Finds all entities of from the database. + /// + /// + /// A task that represents the asynchronous operation. + /// The task result contains a that contains elements from the input sequence. + /// + Task> ListAsync(CancellationToken cancellationToken = default); + + /// + /// Finds all entities of , that matches the encapsulated query logic of the + /// , from the database. + /// + /// The encapsulated query logic. + /// + /// A task that represents the asynchronous operation. + /// The task result contains a that contains elements from the input sequence. + /// + Task> ListAsync(ISpecification specification, CancellationToken cancellationToken = default); + + /// + /// Finds all entities of , that matches the encapsulated query logic of the + /// , from the database. + /// + /// Projects each entity into a new form, being . + /// + /// + /// The type of the value returned by the projection. + /// The encapsulated query logic. + /// + /// A task that represents the asynchronous operation. + /// The task result contains a that contains elements from the input sequence. + /// + Task> ListAsync(ISpecification specification, CancellationToken cancellationToken = default); + + /// + /// Returns a number that represents how many entities satisfy the encapsulated query logic + /// of the . + /// + /// The encapsulated query logic. + /// + /// A task that represents the asynchronous operation. The task result contains the + /// number of elements in the input sequence. + /// + Task CountAsync(ISpecification specification, CancellationToken cancellationToken = default); + + /// + /// Returns the total number of records. + /// + /// + /// A task that represents the asynchronous operation. The task result contains the + /// number of elements in the input sequence. + /// + Task CountAsync(CancellationToken cancellationToken = default); + + /// + /// Returns a boolean that represents whether any entity satisfy the encapsulated query logic + /// of the or not. + /// + /// The encapsulated query logic. + /// + /// A task that represents the asynchronous operation. The task result contains true if the + /// source sequence contains any elements; otherwise, false. + /// + Task AnyAsync(ISpecification specification, CancellationToken cancellationToken = default); + + /// + /// Returns a boolean whether any entity exists or not. + /// + /// + /// A task that represents the asynchronous operation. The task result contains true if the + /// source sequence contains any elements; otherwise, false. + /// + Task AnyAsync(CancellationToken cancellationToken = default); #if NET6_0_OR_GREATER - /// - /// Finds all entities of , that matches the encapsulated query logic of the - /// , from the database. - /// - /// The encapsulated query logic. - /// - /// Returns an IAsyncEnumerable which can be enumerated asynchronously. - /// - IAsyncEnumerable AsAsyncEnumerable(ISpecification specification); + /// + /// Finds all entities of , that matches the encapsulated query logic of the + /// , from the database. + /// + /// The encapsulated query logic. + /// + /// Returns an IAsyncEnumerable which can be enumerated asynchronously. + /// + IAsyncEnumerable AsAsyncEnumerable(ISpecification specification); #endif } diff --git a/Specification/src/Ardalis.Specification/IRepositoryBase.cs b/Specification/src/Ardalis.Specification/IRepositoryBase.cs index 96ad7149..896d854b 100644 --- a/Specification/src/Ardalis.Specification/IRepositoryBase.cs +++ b/Specification/src/Ardalis.Specification/IRepositoryBase.cs @@ -14,59 +14,59 @@ namespace Ardalis.Specification; /// The type of entity being operated on by this repository. public interface IRepositoryBase : IReadRepositoryBase where T : class { - /// - /// Adds an entity in the database. - /// - /// The entity to add. - /// - /// - /// A task that represents the asynchronous operation. - /// The task result contains the . - /// - Task AddAsync(T entity, CancellationToken cancellationToken = default); + /// + /// Adds an entity in the database. + /// + /// The entity to add. + /// + /// + /// A task that represents the asynchronous operation. + /// The task result contains the . + /// + Task AddAsync(T entity, CancellationToken cancellationToken = default); - /// - /// Adds the given entities in the database - /// - /// - /// - /// - /// A task that represents the asynchronous operation. - /// - Task> AddRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default); + /// + /// Adds the given entities in the database + /// + /// + /// + /// + /// A task that represents the asynchronous operation. + /// + Task> AddRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default); - /// - /// Updates an entity in the database - /// - /// The entity to update. - /// A task that represents the asynchronous operation. - Task UpdateAsync(T entity, CancellationToken cancellationToken = default); + /// + /// Updates an entity in the database + /// + /// The entity to update. + /// A task that represents the asynchronous operation. + Task UpdateAsync(T entity, CancellationToken cancellationToken = default); - /// - /// Updates the given entities in the database - /// - /// The entities to update. - /// - /// A task that represents the asynchronous operation. - Task UpdateRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default); + /// + /// Updates the given entities in the database + /// + /// The entities to update. + /// + /// A task that represents the asynchronous operation. + Task UpdateRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default); - /// - /// Removes an entity in the database - /// - /// The entity to delete. - /// A task that represents the asynchronous operation. - Task DeleteAsync(T entity, CancellationToken cancellationToken = default); + /// + /// Removes an entity in the database + /// + /// The entity to delete. + /// A task that represents the asynchronous operation. + Task DeleteAsync(T entity, CancellationToken cancellationToken = default); - /// - /// Removes the given entities in the database - /// - /// The entities to remove. - /// A task that represents the asynchronous operation. - Task DeleteRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default); + /// + /// Removes the given entities in the database + /// + /// The entities to remove. + /// A task that represents the asynchronous operation. + Task DeleteRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default); - /// - /// Persists changes to the database. - /// - /// A task that represents the asynchronous operation. - Task SaveChangesAsync(CancellationToken cancellationToken = default); + /// + /// Persists changes to the database. + /// + /// A task that represents the asynchronous operation. + Task SaveChangesAsync(CancellationToken cancellationToken = default); } diff --git a/Specification/src/Ardalis.Specification/ISpecification.cs b/Specification/src/Ardalis.Specification/ISpecification.cs index 24304d36..a28a9b0e 100644 --- a/Specification/src/Ardalis.Specification/ISpecification.cs +++ b/Specification/src/Ardalis.Specification/ISpecification.cs @@ -12,24 +12,24 @@ namespace Ardalis.Specification; /// The type of the result. public interface ISpecification : ISpecification { - new ISpecificationBuilder Query { get; } + new ISpecificationBuilder Query { get; } - /// - /// The Select transform function to apply to the element. - /// - Expression>? Selector { get; } + /// + /// The Select transform function to apply to the element. + /// + Expression>? Selector { get; } - /// - /// The SelectMany transform function to apply to the element. - /// - Expression>>? SelectorMany { get; } + /// + /// The SelectMany transform function to apply to the element. + /// + Expression>>? SelectorMany { get; } - /// - /// The transform function to apply to the result of the query encapsulated by the . - /// - new Func, IEnumerable>? PostProcessingAction { get; } + /// + /// The transform function to apply to the result of the query encapsulated by the . + /// + new Func, IEnumerable>? PostProcessingAction { get; } - new IEnumerable Evaluate(IEnumerable entities); + new IEnumerable Evaluate(IEnumerable entities); } /// @@ -38,117 +38,117 @@ public interface ISpecification : ISpecification /// The type being queried against. public interface ISpecification { - ISpecificationBuilder Query { get; } - - /// - /// Arbitrary state to be accessed from builders and evaluators. - /// - IDictionary Items { get; set; } - - /// - /// The collection of filters. - /// - IEnumerable> WhereExpressions { get; } - - /// - /// The collections of functions used to determine the sorting (and subsequent sorting), - /// to apply to the result of the query encapsulated by the . - /// - IEnumerable> OrderExpressions { get; } - - /// - /// The collection of s describing each include expression. - /// This information is utilized to build Include/ThenInclude functions in the query. - /// - IEnumerable IncludeExpressions { get; } - - /// - /// The collection of navigation properties, as strings, to include in the query. - /// - IEnumerable IncludeStrings { get; } - - /// - /// The collection of 'SQL LIKE' operations. - /// - IEnumerable> SearchCriterias { get; } - - /// - /// The number of elements to return. - /// - int? Take { get; } - - /// - /// The number of elements to skip before returning the remaining elements. - /// - int? Skip { get; } - - /// - /// The transform function to apply to the result of the query encapsulated by the . - /// - Func, IEnumerable>? PostProcessingAction { get; } - - /// - /// Return whether or not the results should be cached. - /// - bool CacheEnabled { get; } - - /// - /// The identifier to use to store and retrieve results from the cache. - /// - string? CacheKey { get; } - - /// - /// Returns whether or not the change tracker will track any of the entities - /// that are returned. - /// - bool AsTracking { get; } - - /// - /// Returns whether or not the change tracker will track any of the entities - /// that are returned. When true, if the entity instances are modified, this will not be detected - /// by the change tracker. - /// - bool AsNoTracking { get; } - - /// - /// Returns whether or not the generated sql query should be split into multiple SQL queries - /// - /// - /// This feature was introduced in EF Core 5.0. It only works when using Include - /// for more info: https://docs.microsoft.com/en-us/ef/core/querying/single-split-queries - /// - bool AsSplitQuery { get; } - - /// - /// Returns whether or not the query will then keep track of returned instances - /// (without tracking them in the normal way) - /// and ensure no duplicates are created in the query results - /// - /// - /// for more info: https://docs.microsoft.com/en-us/ef/core/change-tracking/identity-resolution#identity-resolution-and-queries - /// - 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 - /// - /// the list of entities to which the specification will be applied - /// - IEnumerable Evaluate(IEnumerable entities); - - /// - /// It returns whether the given entity satisfies the conditions of the specification. - /// - /// The entity to be validated - /// - bool IsSatisfiedBy(T entity); + ISpecificationBuilder Query { get; } + + /// + /// Arbitrary state to be accessed from builders and evaluators. + /// + IDictionary Items { get; set; } + + /// + /// The collection of filters. + /// + IEnumerable> WhereExpressions { get; } + + /// + /// The collections of functions used to determine the sorting (and subsequent sorting), + /// to apply to the result of the query encapsulated by the . + /// + IEnumerable> OrderExpressions { get; } + + /// + /// The collection of s describing each include expression. + /// This information is utilized to build Include/ThenInclude functions in the query. + /// + IEnumerable IncludeExpressions { get; } + + /// + /// The collection of navigation properties, as strings, to include in the query. + /// + IEnumerable IncludeStrings { get; } + + /// + /// The collection of 'SQL LIKE' operations. + /// + IEnumerable> SearchCriterias { get; } + + /// + /// The number of elements to return. + /// + int? Take { get; } + + /// + /// The number of elements to skip before returning the remaining elements. + /// + int? Skip { get; } + + /// + /// The transform function to apply to the result of the query encapsulated by the . + /// + Func, IEnumerable>? PostProcessingAction { get; } + + /// + /// Return whether or not the results should be cached. + /// + bool CacheEnabled { get; } + + /// + /// The identifier to use to store and retrieve results from the cache. + /// + string? CacheKey { get; } + + /// + /// Returns whether or not the change tracker will track any of the entities + /// that are returned. + /// + bool AsTracking { get; } + + /// + /// Returns whether or not the change tracker will track any of the entities + /// that are returned. When true, if the entity instances are modified, this will not be detected + /// by the change tracker. + /// + bool AsNoTracking { get; } + + /// + /// Returns whether or not the generated sql query should be split into multiple SQL queries + /// + /// + /// This feature was introduced in EF Core 5.0. It only works when using Include + /// for more info: https://docs.microsoft.com/en-us/ef/core/querying/single-split-queries + /// + bool AsSplitQuery { get; } + + /// + /// Returns whether or not the query will then keep track of returned instances + /// (without tracking them in the normal way) + /// and ensure no duplicates are created in the query results + /// + /// + /// for more info: https://docs.microsoft.com/en-us/ef/core/change-tracking/identity-resolution#identity-resolution-and-queries + /// + 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 + /// + /// the list of entities to which the specification will be applied + /// + IEnumerable Evaluate(IEnumerable entities); + + /// + /// It returns whether the given entity satisfies the conditions of the specification. + /// + /// The entity to be validated + /// + bool IsSatisfiedBy(T entity); } diff --git a/Specification/src/Ardalis.Specification/IncludeTypeEnum.cs b/Specification/src/Ardalis.Specification/IncludeTypeEnum.cs index 98d160cf..83176da2 100644 --- a/Specification/src/Ardalis.Specification/IncludeTypeEnum.cs +++ b/Specification/src/Ardalis.Specification/IncludeTypeEnum.cs @@ -2,6 +2,6 @@ public enum IncludeTypeEnum { - Include = 1, - ThenInclude = 2 + Include = 1, + ThenInclude = 2 } diff --git a/Specification/src/Ardalis.Specification/OrderTypeEnum.cs b/Specification/src/Ardalis.Specification/OrderTypeEnum.cs index 606dad83..0291805b 100644 --- a/Specification/src/Ardalis.Specification/OrderTypeEnum.cs +++ b/Specification/src/Ardalis.Specification/OrderTypeEnum.cs @@ -5,8 +5,8 @@ /// public enum OrderTypeEnum { - OrderBy = 1, - OrderByDescending = 2, - ThenBy = 3, - ThenByDescending = 4 + OrderBy = 1, + OrderByDescending = 2, + ThenBy = 3, + ThenByDescending = 4 } diff --git a/Specification/src/Ardalis.Specification/Specification.cs b/Specification/src/Ardalis.Specification/Specification.cs index fc9e18e0..7f0c42e2 100644 --- a/Specification/src/Ardalis.Specification/Specification.cs +++ b/Specification/src/Ardalis.Specification/Specification.cs @@ -7,119 +7,119 @@ namespace Ardalis.Specification; /// public class Specification : Specification, ISpecification { - public new virtual ISpecificationBuilder Query { get; } + public new virtual ISpecificationBuilder Query { get; } - protected Specification() - : this(InMemorySpecificationEvaluator.Default) - { - } + protected Specification() + : this(InMemorySpecificationEvaluator.Default) + { + } - protected Specification(IInMemorySpecificationEvaluator inMemorySpecificationEvaluator) - : base(inMemorySpecificationEvaluator) - { - Query = new SpecificationBuilder(this); - } + protected Specification(IInMemorySpecificationEvaluator inMemorySpecificationEvaluator) + : base(inMemorySpecificationEvaluator) + { + Query = new SpecificationBuilder(this); + } - public new virtual IEnumerable Evaluate(IEnumerable entities) - { - return Evaluator.Evaluate(entities, this); - } + public new virtual IEnumerable Evaluate(IEnumerable entities) + { + return Evaluator.Evaluate(entities, this); + } - /// - public Expression>? Selector { get; internal set; } + /// + public Expression>? Selector { get; internal set; } - /// - public Expression>>? SelectorMany { get; internal set; } + /// + public Expression>>? SelectorMany { get; internal set; } - /// - public new Func, IEnumerable>? PostProcessingAction { get; internal set; } = null; + /// + public new Func, IEnumerable>? PostProcessingAction { get; internal set; } = null; } /// public class Specification : ISpecification { - protected IInMemorySpecificationEvaluator Evaluator { get; } - protected ISpecificationValidator Validator { get; } - public virtual ISpecificationBuilder Query { get; } + protected IInMemorySpecificationEvaluator Evaluator { get; } + protected ISpecificationValidator Validator { get; } + public virtual ISpecificationBuilder Query { get; } - protected Specification() - : this(InMemorySpecificationEvaluator.Default, SpecificationValidator.Default) - { - } + protected Specification() + : this(InMemorySpecificationEvaluator.Default, SpecificationValidator.Default) + { + } - protected Specification(IInMemorySpecificationEvaluator inMemorySpecificationEvaluator) - : this(inMemorySpecificationEvaluator, SpecificationValidator.Default) - { - } + protected Specification(IInMemorySpecificationEvaluator inMemorySpecificationEvaluator) + : this(inMemorySpecificationEvaluator, SpecificationValidator.Default) + { + } - protected Specification(ISpecificationValidator specificationValidator) - : this(InMemorySpecificationEvaluator.Default, specificationValidator) - { - } + protected Specification(ISpecificationValidator specificationValidator) + : this(InMemorySpecificationEvaluator.Default, specificationValidator) + { + } - protected Specification(IInMemorySpecificationEvaluator inMemorySpecificationEvaluator, ISpecificationValidator specificationValidator) - { - Evaluator = inMemorySpecificationEvaluator; - Validator = specificationValidator; - Query = new SpecificationBuilder(this); - } + protected Specification(IInMemorySpecificationEvaluator inMemorySpecificationEvaluator, ISpecificationValidator specificationValidator) + { + Evaluator = inMemorySpecificationEvaluator; + Validator = specificationValidator; + Query = new SpecificationBuilder(this); + } - /// - public virtual IEnumerable Evaluate(IEnumerable entities) - { - return Evaluator.Evaluate(entities, this); - } + /// + public virtual IEnumerable Evaluate(IEnumerable entities) + { + return Evaluator.Evaluate(entities, this); + } - /// - public virtual bool IsSatisfiedBy(T entity) - { - return Validator.IsValid(entity, this); - } + /// + public virtual bool IsSatisfiedBy(T entity) + { + return Validator.IsValid(entity, this); + } - /// - public IDictionary Items { get; set; } = new Dictionary(); + /// + public IDictionary Items { get; set; } = new Dictionary(); - /// - public IEnumerable> WhereExpressions { get; } = new List>(); + /// + public IEnumerable> WhereExpressions { get; } = new List>(); - public IEnumerable> OrderExpressions { get; } = new List>(); + public IEnumerable> OrderExpressions { get; } = new List>(); - /// - public IEnumerable IncludeExpressions { get; } = new List(); + /// + public IEnumerable IncludeExpressions { get; } = new List(); - /// - public IEnumerable IncludeStrings { get; } = new List(); + /// + public IEnumerable IncludeStrings { get; } = new List(); - /// - public IEnumerable> SearchCriterias { get; } = new List>(); + /// + public IEnumerable> SearchCriterias { get; } = new List>(); - /// - public int? Take { get; internal set; } = null; + /// + public int? Take { get; internal set; } = null; - /// - public int? Skip { get; internal set; } = null; + /// + public int? Skip { get; internal set; } = null; - /// - public Func, IEnumerable>? PostProcessingAction { get; internal set; } = null; + /// + public Func, IEnumerable>? PostProcessingAction { get; internal set; } = null; - /// - public string? CacheKey { get; internal set; } + /// + public string? CacheKey { get; internal set; } - /// - public bool CacheEnabled { get; internal set; } + /// + public bool CacheEnabled { get; internal set; } - /// - public bool AsTracking { get; internal set; } = false; + /// + public bool AsTracking { get; internal set; } = false; - /// - public bool AsNoTracking { get; internal set; } = false; + /// + public bool AsNoTracking { get; internal set; } = false; - /// - public bool AsSplitQuery { get; internal set; } = false; + /// + public bool AsSplitQuery { get; internal set; } = false; - /// - public bool AsNoTrackingWithIdentityResolution { get; internal set; } = false; + /// + public bool AsNoTrackingWithIdentityResolution { get; internal set; } = false; - /// - public bool IgnoreQueryFilters { get; internal set; } = false; + /// + public bool IgnoreQueryFilters { get; internal set; } = false; } diff --git a/Specification/src/Ardalis.Specification/Validators/ISpecificationValidator.cs b/Specification/src/Ardalis.Specification/Validators/ISpecificationValidator.cs index 8156cb64..701546ef 100644 --- a/Specification/src/Ardalis.Specification/Validators/ISpecificationValidator.cs +++ b/Specification/src/Ardalis.Specification/Validators/ISpecificationValidator.cs @@ -2,5 +2,5 @@ public interface ISpecificationValidator { - bool IsValid(T entity, ISpecification specification); + bool IsValid(T entity, ISpecification specification); } diff --git a/Specification/src/Ardalis.Specification/Validators/IValidator.cs b/Specification/src/Ardalis.Specification/Validators/IValidator.cs index b284636c..31bb718b 100644 --- a/Specification/src/Ardalis.Specification/Validators/IValidator.cs +++ b/Specification/src/Ardalis.Specification/Validators/IValidator.cs @@ -2,5 +2,5 @@ public interface IValidator { - bool IsValid(T entity, ISpecification specification); + bool IsValid(T entity, ISpecification specification); } diff --git a/Specification/src/Ardalis.Specification/Validators/SearchValidator.cs b/Specification/src/Ardalis.Specification/Validators/SearchValidator.cs index 93a48d4d..80079ad1 100644 --- a/Specification/src/Ardalis.Specification/Validators/SearchValidator.cs +++ b/Specification/src/Ardalis.Specification/Validators/SearchValidator.cs @@ -4,16 +4,16 @@ namespace Ardalis.Specification; public class SearchValidator : IValidator { - private SearchValidator() { } - public static SearchValidator Instance { get; } = new SearchValidator(); + private SearchValidator() { } + public static SearchValidator Instance { get; } = new SearchValidator(); - public bool IsValid(T entity, ISpecification specification) - { - foreach (var searchGroup in specification.SearchCriterias.GroupBy(x => x.SearchGroup)) + public bool IsValid(T entity, ISpecification specification) { - if (searchGroup.Any(c => c.SelectorFunc(entity).Like(c.SearchTerm)) == false) return false; - } + foreach (var searchGroup in specification.SearchCriterias.GroupBy(x => x.SearchGroup)) + { + if (searchGroup.Any(c => c.SelectorFunc(entity).Like(c.SearchTerm)) == false) return false; + } - return true; - } + return true; + } } diff --git a/Specification/src/Ardalis.Specification/Validators/SpecificationValidator.cs b/Specification/src/Ardalis.Specification/Validators/SpecificationValidator.cs index c88d5ee8..b2ff6a2c 100644 --- a/Specification/src/Ardalis.Specification/Validators/SpecificationValidator.cs +++ b/Specification/src/Ardalis.Specification/Validators/SpecificationValidator.cs @@ -4,31 +4,31 @@ namespace Ardalis.Specification; public class SpecificationValidator : ISpecificationValidator { - // Will use singleton for default configuration. Yet, it can be instantiated if necessary, with default or provided validators. - public static SpecificationValidator Default { get; } = new SpecificationValidator(); + // Will use singleton for default configuration. Yet, it can be instantiated if necessary, with default or provided validators. + public static SpecificationValidator Default { get; } = new SpecificationValidator(); - private readonly List _validators = new(); + private readonly List _validators = new(); - public SpecificationValidator() - { - _validators.AddRange(new IValidator[] + public SpecificationValidator() { - WhereValidator.Instance, - SearchValidator.Instance - }); - } - public SpecificationValidator(IEnumerable validators) - { - _validators.AddRange(validators); - } - - public virtual bool IsValid(T entity, ISpecification specification) - { - foreach (var partialValidator in _validators) + _validators.AddRange(new IValidator[] + { + WhereValidator.Instance, + SearchValidator.Instance + }); + } + public SpecificationValidator(IEnumerable validators) { - if (partialValidator.IsValid(entity, specification) == false) return false; + _validators.AddRange(validators); } - return true; - } + public virtual bool IsValid(T entity, ISpecification specification) + { + foreach (var partialValidator in _validators) + { + if (partialValidator.IsValid(entity, specification) == false) return false; + } + + return true; + } } diff --git a/Specification/src/Ardalis.Specification/Validators/WhereValidator.cs b/Specification/src/Ardalis.Specification/Validators/WhereValidator.cs index 4e7778d4..2068d9d1 100644 --- a/Specification/src/Ardalis.Specification/Validators/WhereValidator.cs +++ b/Specification/src/Ardalis.Specification/Validators/WhereValidator.cs @@ -2,16 +2,16 @@ public class WhereValidator : IValidator { - private WhereValidator() { } - public static WhereValidator Instance { get; } = new WhereValidator(); + private WhereValidator() { } + public static WhereValidator Instance { get; } = new WhereValidator(); - public bool IsValid(T entity, ISpecification specification) - { - foreach (var info in specification.WhereExpressions) + public bool IsValid(T entity, ISpecification specification) { - if (info.FilterFunc(entity) == false) return false; - } + foreach (var info in specification.WhereExpressions) + { + if (info.FilterFunc(entity) == false) return false; + } - return true; - } + return true; + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/IncludableBuilderExtensions_ThenInclude.cs b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/IncludableBuilderExtensions_ThenInclude.cs index 986f3549..a48ef27f 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/IncludableBuilderExtensions_ThenInclude.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/IncludableBuilderExtensions_ThenInclude.cs @@ -4,46 +4,46 @@ namespace Ardalis.Specification.UnitTests; public class IncludableBuilderExtensions_ThenInclude { - [Fact] - public void AppendIncludeExpressionInfoToListWithTypeThenInclude_GivenThenIncludeExpression() - { - var spec = new StoreIncludeCompanyThenCountrySpec(); + [Fact] + public void AppendIncludeExpressionInfoToListWithTypeThenInclude_GivenThenIncludeExpression() + { + var spec = new StoreIncludeCompanyThenCountrySpec(); - var includeExpressions = spec.IncludeExpressions.ToList(); + var includeExpressions = spec.IncludeExpressions.ToList(); - // The list must have two items, since ThenInclude can be applied once the first level is applied. - includeExpressions.Should().HaveCount(2); + // The list must have two items, since ThenInclude can be applied once the first level is applied. + includeExpressions.Should().HaveCount(2); - includeExpressions[1].Type.Should().Be(IncludeTypeEnum.ThenInclude); - } + includeExpressions[1].Type.Should().Be(IncludeTypeEnum.ThenInclude); + } - [Fact] - public void AddsNothingToList_GivenDiscardedIncludeChain() - { - var spec = new CompanyByIdWithFalseConditions(1); + [Fact] + public void AddsNothingToList_GivenDiscardedIncludeChain() + { + var spec = new CompanyByIdWithFalseConditions(1); - spec.IncludeExpressions.Should().BeEmpty(); - } + spec.IncludeExpressions.Should().BeEmpty(); + } - [Fact] - public void AddsNothingToList_GivenThenIncludeExpressionWithFalseCondition() - { - var spec = new CompanyByIdWithFalseConditionsForInnerChains(1); + [Fact] + public void AddsNothingToList_GivenThenIncludeExpressionWithFalseCondition() + { + var spec = new CompanyByIdWithFalseConditionsForInnerChains(1); - spec.IncludeExpressions.Should().HaveCount(1); - spec.IncludeExpressions.First().Type.Should().Be(IncludeTypeEnum.Include); - spec.IncludeExpressions.Where(x => x.Type == IncludeTypeEnum.ThenInclude).Should().BeEmpty(); - } + spec.IncludeExpressions.Should().HaveCount(1); + spec.IncludeExpressions.First().Type.Should().Be(IncludeTypeEnum.Include); + spec.IncludeExpressions.Where(x => x.Type == IncludeTypeEnum.ThenInclude).Should().BeEmpty(); + } - [Fact] - public void ThenInclude_Append_IncludeExpressionInfo_With_EnumerablePreviousPropertyType() - { - var spec = new StoreIncludeCompanyThenStoresSpec(); + [Fact] + public void ThenInclude_Append_IncludeExpressionInfo_With_EnumerablePreviousPropertyType() + { + var spec = new StoreIncludeCompanyThenStoresSpec(); - var includeExpressions = spec.IncludeExpressions.ToList(); + var includeExpressions = spec.IncludeExpressions.ToList(); - includeExpressions.Should().HaveCount(3); + includeExpressions.Should().HaveCount(3); - includeExpressions[2].PreviousPropertyType.Should().Be(typeof(IEnumerable)); - } + includeExpressions[2].PreviousPropertyType.Should().Be(typeof(IEnumerable)); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/OrderedBuilderExtensions_ThenBy.cs b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/OrderedBuilderExtensions_ThenBy.cs index 60d5f291..7a759f89 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/OrderedBuilderExtensions_ThenBy.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/OrderedBuilderExtensions_ThenBy.cs @@ -2,35 +2,35 @@ public class OrderedBuilderExtensions_ThenBy { - [Fact] - public void AppendOrderExpressionToListWithThenByType_GivenThenByExpression() - { - var spec = new StoresByCompanyOrderedDescByNameThenByIdSpec(1); + [Fact] + public void AppendOrderExpressionToListWithThenByType_GivenThenByExpression() + { + var spec = new StoresByCompanyOrderedDescByNameThenByIdSpec(1); - var orderExpressions = spec.OrderExpressions.ToList(); + var orderExpressions = spec.OrderExpressions.ToList(); - // The list must have two items, since Then can be applied once the first level is applied. - orderExpressions.Should().HaveCount(2); + // The list must have two items, since Then can be applied once the first level is applied. + orderExpressions.Should().HaveCount(2); - orderExpressions[1].OrderType.Should().Be(OrderTypeEnum.ThenBy); - } + orderExpressions[1].OrderType.Should().Be(OrderTypeEnum.ThenBy); + } - [Fact] - public void AddsNothingToList_GivenDiscardedOrderChain() - { - var spec = new CompanyByIdWithFalseConditions(1); + [Fact] + public void AddsNothingToList_GivenDiscardedOrderChain() + { + var spec = new CompanyByIdWithFalseConditions(1); - spec.OrderExpressions.Should().BeEmpty(); - } + spec.OrderExpressions.Should().BeEmpty(); + } - [Fact] - public void AddsNothingToList_GivenThenByExpressionWithFalseCondition() - { - var spec = new CompanyByIdWithFalseConditionsForInnerChains(1); + [Fact] + public void AddsNothingToList_GivenThenByExpressionWithFalseCondition() + { + var spec = new CompanyByIdWithFalseConditionsForInnerChains(1); - spec.OrderExpressions.Should().HaveCount(2); - spec.OrderExpressions.First().OrderType.Should().Be(OrderTypeEnum.OrderBy); - spec.OrderExpressions.Skip(1).First().OrderType.Should().Be(OrderTypeEnum.OrderByDescending); - spec.OrderExpressions.Where(x => x.OrderType == OrderTypeEnum.ThenBy).Should().BeEmpty(); - } + spec.OrderExpressions.Should().HaveCount(2); + spec.OrderExpressions.First().OrderType.Should().Be(OrderTypeEnum.OrderBy); + spec.OrderExpressions.Skip(1).First().OrderType.Should().Be(OrderTypeEnum.OrderByDescending); + spec.OrderExpressions.Where(x => x.OrderType == OrderTypeEnum.ThenBy).Should().BeEmpty(); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/OrderedBuilderExtensions_ThenByDescending.cs b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/OrderedBuilderExtensions_ThenByDescending.cs index 7ac2d4e2..fe67a494 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/OrderedBuilderExtensions_ThenByDescending.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/OrderedBuilderExtensions_ThenByDescending.cs @@ -2,35 +2,35 @@ public class OrderedBuilderExtensions_ThenByDescending { - [Fact] - public void AppendsOrderExpressionToListWithThenByDescendingType_GivenThenByDescendingExpression() - { - var spec = new StoresByCompanyOrderedDescByNameThenByDescIdSpec(1); + [Fact] + public void AppendsOrderExpressionToListWithThenByDescendingType_GivenThenByDescendingExpression() + { + var spec = new StoresByCompanyOrderedDescByNameThenByDescIdSpec(1); - var orderExpressions = spec.OrderExpressions.ToList(); + var orderExpressions = spec.OrderExpressions.ToList(); - // The list must have two items, since Then can be applied once the first level is applied. - orderExpressions.Should().HaveCount(2); + // The list must have two items, since Then can be applied once the first level is applied. + orderExpressions.Should().HaveCount(2); - orderExpressions[1].OrderType.Should().Be(OrderTypeEnum.ThenByDescending); - } + orderExpressions[1].OrderType.Should().Be(OrderTypeEnum.ThenByDescending); + } - [Fact] - public void AddsNothingToList_GivenDiscardedOrderChain() - { - var spec = new CompanyByIdWithFalseConditions(1); + [Fact] + public void AddsNothingToList_GivenDiscardedOrderChain() + { + var spec = new CompanyByIdWithFalseConditions(1); - spec.OrderExpressions.Should().BeEmpty(); - } + spec.OrderExpressions.Should().BeEmpty(); + } - [Fact] - public void AddsNothingToList_GivenThenByDescendingExpressionWithFalseCondition() - { - var spec = new CompanyByIdWithFalseConditionsForInnerChains(1); + [Fact] + public void AddsNothingToList_GivenThenByDescendingExpressionWithFalseCondition() + { + var spec = new CompanyByIdWithFalseConditionsForInnerChains(1); - spec.OrderExpressions.Should().HaveCount(2); - spec.OrderExpressions.First().OrderType.Should().Be(OrderTypeEnum.OrderBy); - spec.OrderExpressions.Skip(1).First().OrderType.Should().Be(OrderTypeEnum.OrderByDescending); - spec.OrderExpressions.Where(x => x.OrderType == OrderTypeEnum.ThenByDescending).Should().BeEmpty(); - } + spec.OrderExpressions.Should().HaveCount(2); + spec.OrderExpressions.First().OrderType.Should().Be(OrderTypeEnum.OrderBy); + spec.OrderExpressions.Skip(1).First().OrderType.Should().Be(OrderTypeEnum.OrderByDescending); + spec.OrderExpressions.Where(x => x.OrderType == OrderTypeEnum.ThenByDescending).Should().BeEmpty(); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_AsNoTracking.cs b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_AsNoTracking.cs index cdb4187a..3caf3983 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_AsNoTracking.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_AsNoTracking.cs @@ -2,35 +2,35 @@ public class SpecificationBuilderExtensions_AsNoTracking { - [Fact] - public void DoesNothing_GivenSpecWithoutAsNoTracking() - { - var spec = new StoreEmptySpec(); + [Fact] + public void DoesNothing_GivenSpecWithoutAsNoTracking() + { + var spec = new StoreEmptySpec(); - spec.AsNoTracking.Should().Be(false); - } + spec.AsNoTracking.Should().Be(false); + } - [Fact] - public void DoesNothing_GivenAsNoTrackingWithFalseCondition() - { - var spec = new CompanyByIdWithFalseConditions(1); + [Fact] + public void DoesNothing_GivenAsNoTrackingWithFalseCondition() + { + var spec = new CompanyByIdWithFalseConditions(1); - spec.AsNoTracking.Should().Be(false); - } + spec.AsNoTracking.Should().Be(false); + } - [Fact] - public void FlagsAsNoTracking_GivenSpecWithAsNoTracking() - { - var spec = new CompanyByIdAsUntrackedSpec(1); + [Fact] + public void FlagsAsNoTracking_GivenSpecWithAsNoTracking() + { + var spec = new CompanyByIdAsUntrackedSpec(1); - spec.AsNoTracking.Should().Be(true); - } + spec.AsNoTracking.Should().Be(true); + } - [Fact] - public void FlagsAsNoTracking_GivenSpecWithAsTrackingAndEndWithAsNoTracking() - { - var spec = new CompanyByIdWithAsTrackingAsUntrackedSpec(1); + [Fact] + public void FlagsAsNoTracking_GivenSpecWithAsTrackingAndEndWithAsNoTracking() + { + var spec = new CompanyByIdWithAsTrackingAsUntrackedSpec(1); - spec.AsNoTracking.Should().Be(true); - } + spec.AsNoTracking.Should().Be(true); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_AsNoTrackingWithIdentityResolution.cs b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_AsNoTrackingWithIdentityResolution.cs index 78a86746..d6a20829 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_AsNoTrackingWithIdentityResolution.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_AsNoTrackingWithIdentityResolution.cs @@ -2,35 +2,35 @@ public class SpecificationBuilderExtensions_AsNoTrackingWithIdentityResolution { - [Fact] - public void DoesNothing_GivenSpecWithoutAsNoTrackingWithIdentityResolution() - { - var spec = new StoreEmptySpec(); + [Fact] + public void DoesNothing_GivenSpecWithoutAsNoTrackingWithIdentityResolution() + { + var spec = new StoreEmptySpec(); - spec.AsNoTrackingWithIdentityResolution.Should().Be(false); - } + spec.AsNoTrackingWithIdentityResolution.Should().Be(false); + } - [Fact] - public void DoesNothing_GivenAsNoTrackingWithIdentityResolutionWithFalseCondition() - { - var spec = new CompanyByIdWithFalseConditions(1); + [Fact] + public void DoesNothing_GivenAsNoTrackingWithIdentityResolutionWithFalseCondition() + { + var spec = new CompanyByIdWithFalseConditions(1); - spec.AsNoTrackingWithIdentityResolution.Should().Be(false); - } + spec.AsNoTrackingWithIdentityResolution.Should().Be(false); + } - [Fact] - public void FlagsAsNoTracking_GivenSpecWithAsNoTrackingWithIdentityResolution() - { - var spec = new CompanyByIdAsUntrackedWithIdentityResolutionSpec(1); + [Fact] + public void FlagsAsNoTracking_GivenSpecWithAsNoTrackingWithIdentityResolution() + { + var spec = new CompanyByIdAsUntrackedWithIdentityResolutionSpec(1); - spec.AsNoTrackingWithIdentityResolution.Should().Be(true); - } + spec.AsNoTrackingWithIdentityResolution.Should().Be(true); + } - [Fact] - public void FlagsAsNoTracking_GivenSpecWithAsTrackingAndEndWithAsNoTrackingWithIdentityResolution() - { - var spec = new CompanyByIdWithAsTrackingAsUntrackedWithIdentityResolutionSpec(1); + [Fact] + public void FlagsAsNoTracking_GivenSpecWithAsTrackingAndEndWithAsNoTrackingWithIdentityResolution() + { + var spec = new CompanyByIdWithAsTrackingAsUntrackedWithIdentityResolutionSpec(1); - spec.AsNoTrackingWithIdentityResolution.Should().Be(true); - } + spec.AsNoTrackingWithIdentityResolution.Should().Be(true); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_AsSplitQuery.cs b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_AsSplitQuery.cs index a8f46e39..58260597 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_AsSplitQuery.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_AsSplitQuery.cs @@ -2,27 +2,27 @@ public class SpecificationBuilderExtensions_AsSplitQuery { - [Fact] - public void DoesNothing_GivenSpecWithoutAsSplitQuery() - { - var spec = new StoreEmptySpec(); + [Fact] + public void DoesNothing_GivenSpecWithoutAsSplitQuery() + { + var spec = new StoreEmptySpec(); - spec.AsSplitQuery.Should().Be(false); - } + spec.AsSplitQuery.Should().Be(false); + } - [Fact] - public void DoesNothing_GivenAsSplitQueryWithFalseCondition() - { - var spec = new CompanyByIdWithFalseConditions(1); + [Fact] + public void DoesNothing_GivenAsSplitQueryWithFalseCondition() + { + var spec = new CompanyByIdWithFalseConditions(1); - spec.AsSplitQuery.Should().Be(false); - } + spec.AsSplitQuery.Should().Be(false); + } - [Fact] - public void FlagsAsNoTracking_GivenSpecWithAsSplitQuery() - { - var spec = new CompanyByIdAsSplitQuery(1); + [Fact] + public void FlagsAsNoTracking_GivenSpecWithAsSplitQuery() + { + var spec = new CompanyByIdAsSplitQuery(1); - spec.AsSplitQuery.Should().Be(true); - } + spec.AsSplitQuery.Should().Be(true); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_AsTracking.cs b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_AsTracking.cs index 953f3ea3..a8b2c75b 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_AsTracking.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_AsTracking.cs @@ -2,35 +2,35 @@ public class SpecificationBuilderExtensions_AsTracking { - [Fact] - public void DoesNothing_GivenSpecWithoutAsTracking() - { - var spec = new StoreEmptySpec(); + [Fact] + public void DoesNothing_GivenSpecWithoutAsTracking() + { + var spec = new StoreEmptySpec(); - spec.AsTracking.Should().Be(false); - } + spec.AsTracking.Should().Be(false); + } - [Fact] - public void DoesNothing_GivenAsTrackingWithFalseCondition() - { - var spec = new CompanyByIdWithFalseConditions(1); + [Fact] + public void DoesNothing_GivenAsTrackingWithFalseCondition() + { + var spec = new CompanyByIdWithFalseConditions(1); - spec.AsTracking.Should().Be(false); - } + spec.AsTracking.Should().Be(false); + } - [Fact] - public void FlagsAsTracking_GivenSpecWithAsTracking() - { - var spec = new CompanyByIdAsTrackedSpec(1); + [Fact] + public void FlagsAsTracking_GivenSpecWithAsTracking() + { + var spec = new CompanyByIdAsTrackedSpec(1); - spec.AsTracking.Should().Be(true); - } + spec.AsTracking.Should().Be(true); + } - [Fact] - public void FlagsAsTracking_GivenSpecWithAsNoTrackingAndEndWithAsTracking() - { - var spec = new CompanyByIdWithAsNoTrackingAsTrackedSpec(1); + [Fact] + public void FlagsAsTracking_GivenSpecWithAsNoTrackingAndEndWithAsTracking() + { + var spec = new CompanyByIdWithAsNoTrackingAsTrackedSpec(1); - spec.AsTracking.Should().Be(true); - } + spec.AsTracking.Should().Be(true); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_IgnoreQueryFilters.cs b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_IgnoreQueryFilters.cs index e27ac124..74e79f25 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_IgnoreQueryFilters.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_IgnoreQueryFilters.cs @@ -2,27 +2,27 @@ public class SpecificationBuilderExtensions_IgnoreQueryFilters { - [Fact] - public void DoesNothing_GivenSpecWithoutIgnoreQueryFilters() - { - var spec = new StoreEmptySpec(); + [Fact] + public void DoesNothing_GivenSpecWithoutIgnoreQueryFilters() + { + var spec = new StoreEmptySpec(); - spec.IgnoreQueryFilters.Should().Be(false); - } + spec.IgnoreQueryFilters.Should().Be(false); + } - [Fact] - public void DoesNothing_GivenIgnoreQueryFiltersWithFalseCondition() - { - var spec = new CompanyByIdWithFalseConditions(1); + [Fact] + public void DoesNothing_GivenIgnoreQueryFiltersWithFalseCondition() + { + var spec = new CompanyByIdWithFalseConditions(1); - spec.IgnoreQueryFilters.Should().Be(false); - } + spec.IgnoreQueryFilters.Should().Be(false); + } - [Fact] - public void FlagsIgnoreQueryFilters_GivenSpecWithIgnoreQueryFilters() - { - var spec = new CompanyByIdIgnoreQueryFilters(1); + [Fact] + public void FlagsIgnoreQueryFilters_GivenSpecWithIgnoreQueryFilters() + { + var spec = new CompanyByIdIgnoreQueryFilters(1); - spec.IgnoreQueryFilters.Should().Be(true); - } + spec.IgnoreQueryFilters.Should().Be(true); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Include.cs b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Include.cs index beca64de..a1e12aeb 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Include.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Include.cs @@ -2,28 +2,28 @@ public class SpecificationBuilderExtensions_Include { - [Fact] - public void AddsNothingToList_GivenNoIncludeExpression() - { - var spec = new StoreEmptySpec(); + [Fact] + public void AddsNothingToList_GivenNoIncludeExpression() + { + var spec = new StoreEmptySpec(); - spec.IncludeExpressions.Should().BeEmpty(); - } + spec.IncludeExpressions.Should().BeEmpty(); + } - [Fact] - public void AddsNothingToList_GivenIncludeExpressionWithFalseCondition() - { - var spec = new CompanyByIdWithFalseConditions(1); + [Fact] + public void AddsNothingToList_GivenIncludeExpressionWithFalseCondition() + { + var spec = new CompanyByIdWithFalseConditions(1); - spec.IncludeExpressions.Should().BeEmpty(); - } + spec.IncludeExpressions.Should().BeEmpty(); + } - [Fact] - public void AddsIncludeExpressionInfoToListWithTypeInclude_GivenIncludeExpression() - { - var spec = new StoreIncludeAddressSpec(); + [Fact] + public void AddsIncludeExpressionInfoToListWithTypeInclude_GivenIncludeExpression() + { + var spec = new StoreIncludeAddressSpec(); - spec.IncludeExpressions.Should().ContainSingle(); - spec.IncludeExpressions.Single().Type.Should().Be(IncludeTypeEnum.Include); - } + spec.IncludeExpressions.Should().ContainSingle(); + spec.IncludeExpressions.Single().Type.Should().Be(IncludeTypeEnum.Include); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_IncludeString.cs b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_IncludeString.cs index b20a4c9c..eaf1c44f 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_IncludeString.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_IncludeString.cs @@ -2,30 +2,30 @@ public class SpecificationBuilderExtensions_IncludeString { - [Fact] - public void AddsNothingToList_GivenNoIncludeStringExpression() - { - var spec = new StoreEmptySpec(); + [Fact] + public void AddsNothingToList_GivenNoIncludeStringExpression() + { + var spec = new StoreEmptySpec(); - spec.WhereExpressions.Should().BeEmpty(); - } + spec.WhereExpressions.Should().BeEmpty(); + } - [Fact] - public void AddsNothingToList_GivenIncludeStringWithFalseCondition() - { - var spec = new CompanyByIdWithFalseConditions(1); + [Fact] + public void AddsNothingToList_GivenIncludeStringWithFalseCondition() + { + var spec = new CompanyByIdWithFalseConditions(1); - spec.IncludeStrings.Should().BeEmpty(); - } + spec.IncludeStrings.Should().BeEmpty(); + } - [Fact] - public void AddsIncludeStringToList_GivenString() - { - var spec = new StoreIncludeCompanyThenCountryAsStringSpec(); + [Fact] + public void AddsIncludeStringToList_GivenString() + { + var spec = new StoreIncludeCompanyThenCountryAsStringSpec(); - var expected = $"{nameof(Company)}.{nameof(Company.Country)}"; + var expected = $"{nameof(Company)}.{nameof(Company.Country)}"; - spec.IncludeStrings.Should().ContainSingle(); - spec.IncludeStrings.Single().Should().Be(expected); - } + spec.IncludeStrings.Should().ContainSingle(); + spec.IncludeStrings.Single().Should().Be(expected); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_OrderBy.cs b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_OrderBy.cs index 7c58b511..e5b96c70 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_OrderBy.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_OrderBy.cs @@ -2,28 +2,28 @@ public class SpecificationBuilderExtensions_OrderBy { - [Fact] - public void AddsNothingToList_GivenNoOrderExpression() - { - var spec = new StoreEmptySpec(); + [Fact] + public void AddsNothingToList_GivenNoOrderExpression() + { + var spec = new StoreEmptySpec(); - spec.OrderExpressions.Should().BeEmpty(); - } + spec.OrderExpressions.Should().BeEmpty(); + } - [Fact] - public void AddsNothingToList_GivenOrderExpressionWithFalseCondition() - { - var spec = new CompanyByIdWithFalseConditions(1); + [Fact] + public void AddsNothingToList_GivenOrderExpressionWithFalseCondition() + { + var spec = new CompanyByIdWithFalseConditions(1); - spec.OrderExpressions.Should().BeEmpty(); - } + spec.OrderExpressions.Should().BeEmpty(); + } - [Fact] - public void AddsOrderExpressionToListWithOrderByType_GivenOrderByExpression() - { - var spec = new StoresOrderedSpecByName(); + [Fact] + public void AddsOrderExpressionToListWithOrderByType_GivenOrderByExpression() + { + var spec = new StoresOrderedSpecByName(); - spec.OrderExpressions.Should().ContainSingle(); - spec.OrderExpressions.Single().OrderType.Should().Be(OrderTypeEnum.OrderBy); - } + spec.OrderExpressions.Should().ContainSingle(); + spec.OrderExpressions.Single().OrderType.Should().Be(OrderTypeEnum.OrderBy); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_OrderByDescending.cs b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_OrderByDescending.cs index 227ffb6f..42f586e8 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_OrderByDescending.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_OrderByDescending.cs @@ -2,28 +2,28 @@ public class SpecificationBuilderExtensions_OrderByDescending { - [Fact] - public void AddsNothingToList_GivenNoOrderExpression() - { - var spec = new StoreEmptySpec(); + [Fact] + public void AddsNothingToList_GivenNoOrderExpression() + { + var spec = new StoreEmptySpec(); - spec.OrderExpressions.Should().BeEmpty(); - } + spec.OrderExpressions.Should().BeEmpty(); + } - [Fact] - public void AddsNothingToList_GivenOrderExpressionWithFalseCondition() - { - var spec = new CompanyByIdWithFalseConditions(1); + [Fact] + public void AddsNothingToList_GivenOrderExpressionWithFalseCondition() + { + var spec = new CompanyByIdWithFalseConditions(1); - spec.OrderExpressions.Should().BeEmpty(); - } + spec.OrderExpressions.Should().BeEmpty(); + } - [Fact] - public void AddsOrderExpressionToListWithOrderByDescendingType_GivenOrderByDescendingExpression() - { - var spec = new StoresOrderedDescendingByNameSpec(); + [Fact] + public void AddsOrderExpressionToListWithOrderByDescendingType_GivenOrderByDescendingExpression() + { + var spec = new StoresOrderedDescendingByNameSpec(); - spec.OrderExpressions.Should().ContainSingle(); - spec.OrderExpressions.Single().OrderType.Should().Be(OrderTypeEnum.OrderByDescending); - } + spec.OrderExpressions.Should().ContainSingle(); + spec.OrderExpressions.Single().OrderType.Should().Be(OrderTypeEnum.OrderByDescending); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_PostProcessingAction.cs b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_PostProcessingAction.cs index 58c0d483..cd6bfb68 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_PostProcessingAction.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_PostProcessingAction.cs @@ -2,35 +2,35 @@ public class SpecificationBuilderExtensions_PostProcessingAction { - [Fact] - public void SetsNothing_GivenNoPostProcessingAction() - { - var spec = new StoreEmptySpec(); + [Fact] + public void SetsNothing_GivenNoPostProcessingAction() + { + var spec = new StoreEmptySpec(); - spec.PostProcessingAction.Should().BeNull(); - } + spec.PostProcessingAction.Should().BeNull(); + } - [Fact] - public void SetsNothing_GivenSelectorSpecWithNoPostProcessingAction() - { - var spec = new StoreNamesEmptySpec(); + [Fact] + public void SetsNothing_GivenSelectorSpecWithNoPostProcessingAction() + { + var spec = new StoreNamesEmptySpec(); - spec.PostProcessingAction.Should().BeNull(); - } + spec.PostProcessingAction.Should().BeNull(); + } - [Fact] - public void SetsPostProcessingPredicate_GivenPostProcessingAction() - { - var spec = new StoreWithPostProcessingActionSpec(); + [Fact] + public void SetsPostProcessingPredicate_GivenPostProcessingAction() + { + var spec = new StoreWithPostProcessingActionSpec(); - spec.PostProcessingAction.Should().NotBeNull(); - } + spec.PostProcessingAction.Should().NotBeNull(); + } - [Fact] - public void SetsPostProcessingPredicate_GivenSelectorSpecWithPostProcessingAction() - { - var spec = new StoreNamesWithPostProcessingActionSpec(); + [Fact] + public void SetsPostProcessingPredicate_GivenSelectorSpecWithPostProcessingAction() + { + var spec = new StoreNamesWithPostProcessingActionSpec(); - spec.PostProcessingAction.Should().NotBeNull(); - } + spec.PostProcessingAction.Should().NotBeNull(); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Search.cs b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Search.cs index f32c2f08..cb32a075 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Search.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Search.cs @@ -2,54 +2,54 @@ public class SpecificationBuilderExtensions_Search { - [Fact] - public void AddsNothingToList_GivenNoWhereExpression() - { - var spec = new StoreEmptySpec(); - - spec.SearchCriterias.Should().BeEmpty(); - } - - [Fact] - public void AddsNothingToList_GivenSearchExpressionWithFalseCondition() - { - var spec = new CompanyByIdWithFalseConditions(1); - - spec.SearchCriterias.Should().BeEmpty(); - } - - [Fact] - public void AddsOneCriteriaWithDefaultGroupToList_GivenOneSearchExpressionWithNoGroup() - { - var spec = new StoreSearchByNameSpec("test"); - - spec.SearchCriterias.Should().ContainSingle(); - spec.SearchCriterias.Single().SearchTerm.Should().Be("%test%"); - spec.SearchCriterias.Single().SearchGroup.Should().Be(1); - } - - [Fact] - public void AddsTwoCriteriaWithSameGroupToList_GivenTwoSearchExpressionWithNoGroup() - { - var spec = new StoreSearchByNameOrCitySpec("test"); - - var criterias = spec.SearchCriterias.ToList(); - - criterias.Should().HaveCount(2); - criterias.ForEach(x => x.SearchTerm.Should().Be("%test%")); - criterias.ForEach(x => x.SearchGroup.Should().Be(1)); - } - - [Fact] - public void AddsTwoCriteriaWithDifferentGroupToList_GivenTwoSearchExpressionWithDistinctGroup() - { - var spec = new StoreSearchByNameAndCitySpec("test"); - - var criterias = spec.SearchCriterias.ToList(); - - criterias.Should().HaveCount(2); - criterias.ForEach(x => x.SearchTerm.Should().Be("%test%")); - criterias[0].SearchGroup.Should().Be(1); - criterias[1].SearchGroup.Should().Be(2); - } + [Fact] + public void AddsNothingToList_GivenNoWhereExpression() + { + var spec = new StoreEmptySpec(); + + spec.SearchCriterias.Should().BeEmpty(); + } + + [Fact] + public void AddsNothingToList_GivenSearchExpressionWithFalseCondition() + { + var spec = new CompanyByIdWithFalseConditions(1); + + spec.SearchCriterias.Should().BeEmpty(); + } + + [Fact] + public void AddsOneCriteriaWithDefaultGroupToList_GivenOneSearchExpressionWithNoGroup() + { + var spec = new StoreSearchByNameSpec("test"); + + spec.SearchCriterias.Should().ContainSingle(); + spec.SearchCriterias.Single().SearchTerm.Should().Be("%test%"); + spec.SearchCriterias.Single().SearchGroup.Should().Be(1); + } + + [Fact] + public void AddsTwoCriteriaWithSameGroupToList_GivenTwoSearchExpressionWithNoGroup() + { + var spec = new StoreSearchByNameOrCitySpec("test"); + + var criterias = spec.SearchCriterias.ToList(); + + criterias.Should().HaveCount(2); + criterias.ForEach(x => x.SearchTerm.Should().Be("%test%")); + criterias.ForEach(x => x.SearchGroup.Should().Be(1)); + } + + [Fact] + public void AddsTwoCriteriaWithDifferentGroupToList_GivenTwoSearchExpressionWithDistinctGroup() + { + var spec = new StoreSearchByNameAndCitySpec("test"); + + var criterias = spec.SearchCriterias.ToList(); + + criterias.Should().HaveCount(2); + criterias.ForEach(x => x.SearchTerm.Should().Be("%test%")); + criterias[0].SearchGroup.Should().Be(1); + criterias[1].SearchGroup.Should().Be(2); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Select.cs b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Select.cs index f11dae26..d979a9a8 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Select.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Select.cs @@ -2,19 +2,19 @@ public class SpecificationBuilderExtensions_Select { - [Fact] - public void SetsNothing_GivenNoSelectExpression() - { - var spec = new StoreNamesEmptySpec(); + [Fact] + public void SetsNothing_GivenNoSelectExpression() + { + var spec = new StoreNamesEmptySpec(); - spec.Selector.Should().BeNull(); - } + spec.Selector.Should().BeNull(); + } - [Fact] - public void SetsSelector_GivenSelectExpression() - { - var spec = new StoreNamesSpec(); + [Fact] + public void SetsSelector_GivenSelectExpression() + { + var spec = new StoreNamesSpec(); - spec.Selector.Should().NotBeNull(); - } + spec.Selector.Should().NotBeNull(); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_SelectMany.cs b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_SelectMany.cs index 01f78d0e..18ffd968 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_SelectMany.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_SelectMany.cs @@ -2,19 +2,19 @@ public class SpecificationBuilderExtensions_SelectMany { - [Fact] - public void SetsNothing_GivenNoSelectManyExpression() - { - var spec = new StoreProductNamesEmptySpec(); + [Fact] + public void SetsNothing_GivenNoSelectManyExpression() + { + var spec = new StoreProductNamesEmptySpec(); - spec.SelectorMany.Should().BeNull(); - } + spec.SelectorMany.Should().BeNull(); + } - [Fact] - public void SetsSelectorMany_GivenSelectManyExpression() - { - var spec = new StoreProductNamesSpec(); + [Fact] + public void SetsSelectorMany_GivenSelectManyExpression() + { + var spec = new StoreProductNamesSpec(); - spec.SelectorMany.Should().NotBeNull(); - } + spec.SelectorMany.Should().NotBeNull(); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Skip.cs b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Skip.cs index eba5d262..afffca84 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Skip.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Skip.cs @@ -4,32 +4,32 @@ namespace Ardalis.Specification.UnitTests; public class SpecificationBuilderExtensions_Skip { - [Fact] - public void SetsSkipProperty_GivenValue() - { - var skip = 1; - - var spec = new StoreNamesPaginatedSpec(skip, 10); - - spec.Skip.Should() - .Be(skip); - } - - [Fact] - public void DoesNothing_GivenSkipWithFalseCondition() - { - var spec = new CompanyByIdWithFalseConditions(1); - - spec.Skip.Should().BeNull(); - } - - [Fact] - public void ThrowsDuplicateSkipException_GivenSkipUsedMoreThanOnce() - { - Action sutAction = () => new StoreDuplicateSkipSpec(); - - sutAction.Should() - .Throw() - .WithMessage("Duplicate use of Skip(). Ensure you don't use Skip() more than once in the same specification!"); - } + [Fact] + public void SetsSkipProperty_GivenValue() + { + var skip = 1; + + var spec = new StoreNamesPaginatedSpec(skip, 10); + + spec.Skip.Should() + .Be(skip); + } + + [Fact] + public void DoesNothing_GivenSkipWithFalseCondition() + { + var spec = new CompanyByIdWithFalseConditions(1); + + spec.Skip.Should().BeNull(); + } + + [Fact] + public void ThrowsDuplicateSkipException_GivenSkipUsedMoreThanOnce() + { + Action sutAction = () => new StoreDuplicateSkipSpec(); + + sutAction.Should() + .Throw() + .WithMessage("Duplicate use of Skip(). Ensure you don't use Skip() more than once in the same specification!"); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Take.cs b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Take.cs index ab65ee14..4c976e4b 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Take.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Take.cs @@ -4,30 +4,30 @@ namespace Ardalis.Specification.UnitTests; public class SpecificationBuilderExtensions_Take { - [Fact] - public void SetsTakeProperty_GivenValue() - { - var take = 10; - var spec = new StoreNamesPaginatedSpec(0, take); + [Fact] + public void SetsTakeProperty_GivenValue() + { + var take = 10; + var spec = new StoreNamesPaginatedSpec(0, take); - spec.Take.Should().Be(take); - } + spec.Take.Should().Be(take); + } - [Fact] - public void DoesNothing_GivenTakeWithFalseCondition() - { - var spec = new CompanyByIdWithFalseConditions(1); + [Fact] + public void DoesNothing_GivenTakeWithFalseCondition() + { + var spec = new CompanyByIdWithFalseConditions(1); - spec.Take.Should().BeNull(); - } + spec.Take.Should().BeNull(); + } - [Fact] - public void ThrowsDuplicateTakeException_GivenTakeUsedMoreThanOnce() - { - Action sutAction = () => new StoreDuplicateTakeSpec(); + [Fact] + public void ThrowsDuplicateTakeException_GivenTakeUsedMoreThanOnce() + { + Action sutAction = () => new StoreDuplicateTakeSpec(); - sutAction.Should() - .Throw() - .WithMessage("Duplicate use of Take(). Ensure you don't use Take() more than once in the same specification!"); - } + sutAction.Should() + .Throw() + .WithMessage("Duplicate use of Take(). Ensure you don't use Take() more than once in the same specification!"); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Where.cs b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Where.cs index 0623c456..7a14457d 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Where.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/BuilderTests/SpecificationBuilderExtensions_Where.cs @@ -2,35 +2,35 @@ public class SpecificationBuilderExtensions_Where { - [Fact] - public void AddsNothingToList_GivenNoWhereExpression() - { - var spec = new StoreEmptySpec(); + [Fact] + public void AddsNothingToList_GivenNoWhereExpression() + { + var spec = new StoreEmptySpec(); - spec.WhereExpressions.Should().BeEmpty(); - } + spec.WhereExpressions.Should().BeEmpty(); + } - [Fact] - public void AddsNothingToList_GivenWhereExpressionWithFalseCondition() - { - var spec = new CompanyByIdWithFalseConditions(1); + [Fact] + public void AddsNothingToList_GivenWhereExpressionWithFalseCondition() + { + var spec = new CompanyByIdWithFalseConditions(1); - spec.WhereExpressions.Should().BeEmpty(); - } + spec.WhereExpressions.Should().BeEmpty(); + } - [Fact] - public void AddsOneExpressionToList_GivenOneWhereExpression() - { - var spec = new StoreByIdSpec(1); + [Fact] + public void AddsOneExpressionToList_GivenOneWhereExpression() + { + var spec = new StoreByIdSpec(1); - spec.WhereExpressions.Should().ContainSingle(); - } + spec.WhereExpressions.Should().ContainSingle(); + } - [Fact] - public void AddsTwoExpressionsToList_GivenTwoWhereExpressions() - { - var spec = new StoreByIdAndNameSpec(1, "name"); + [Fact] + public void AddsTwoExpressionsToList_GivenTwoWhereExpressions() + { + var spec = new StoreByIdAndNameSpec(1, "name"); - spec.WhereExpressions.Should().HaveCount(2); - } + spec.WhereExpressions.Should().HaveCount(2); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/EvaluatorTests/InMemorySpecificationEvaluatorTests.cs b/Specification/tests/Ardalis.Specification.UnitTests/EvaluatorTests/InMemorySpecificationEvaluatorTests.cs index 357f07e2..d856c4d5 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/EvaluatorTests/InMemorySpecificationEvaluatorTests.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/EvaluatorTests/InMemorySpecificationEvaluatorTests.cs @@ -5,142 +5,142 @@ namespace Ardalis.Specification.UnitTests; public class InMemorySpecificationEvaluatorTests { - [Fact] - public void ReturnsStoreWithId10_GivenStoreByIdSpec() - { - var spec = new StoreByIdSpec(10); + [Fact] + public void ReturnsStoreWithId10_GivenStoreByIdSpec() + { + var spec = new StoreByIdSpec(10); - var store = spec.Evaluate(StoreSeed.Get()).FirstOrDefault(); + var store = spec.Evaluate(StoreSeed.Get()).FirstOrDefault(); - store?.Id.Should().Be(10); - } + store?.Id.Should().Be(10); + } - [Fact] - public void ReturnsStoreWithIdFrom15To30_GivenStoresByIdListSpec() - { - var ids = Enumerable.Range(15, 16); - var spec = new StoresByIdListSpec(ids); + [Fact] + public void ReturnsStoreWithIdFrom15To30_GivenStoresByIdListSpec() + { + var ids = Enumerable.Range(15, 16); + var spec = new StoresByIdListSpec(ids); - var stores = spec.Evaluate(StoreSeed.Get()); + var stores = spec.Evaluate(StoreSeed.Get()); - stores.Count().Should().Be(16); - stores.OrderBy(x => x.Id).First().Id.Should().Be(15); - stores.OrderBy(x => x.Id).Last().Id.Should().Be(30); - } + stores.Count().Should().Be(16); + stores.OrderBy(x => x.Id).First().Id.Should().Be(15); + stores.OrderBy(x => x.Id).Last().Id.Should().Be(30); + } - [Fact] - public void ReturnsSecondPageOfStoreNames_GivenStoreNamesPaginatedSpec() - { - var take = 10; // pagesize 10 - var skip = (2 - 1) * 10; // page 2 + [Fact] + public void ReturnsSecondPageOfStoreNames_GivenStoreNamesPaginatedSpec() + { + var take = 10; // pagesize 10 + var skip = (2 - 1) * 10; // page 2 - var spec = new StoreNamesPaginatedSpec(skip, take); + var spec = new StoreNamesPaginatedSpec(skip, take); - var storeNames = spec.Evaluate(StoreSeed.Get()); + var storeNames = spec.Evaluate(StoreSeed.Get()); - storeNames.Count().Should().Be(take); - storeNames.First().Should().Be("Store 11"); - storeNames.Last().Should().Be("Store 20"); - } + storeNames.Count().Should().Be(take); + storeNames.First().Should().Be("Store 11"); + storeNames.Last().Should().Be("Store 20"); + } - [Fact] - public void ReturnsSecondPageOfStores_GivenStoresPaginatedSpec() - { - var take = 10; // pagesize 10 - var skip = (2 - 1) * 10; // page 2 + [Fact] + public void ReturnsSecondPageOfStores_GivenStoresPaginatedSpec() + { + var take = 10; // pagesize 10 + var skip = (2 - 1) * 10; // page 2 - var spec = new StoresPaginatedSpec(skip, take); + var spec = new StoresPaginatedSpec(skip, take); - var stores = spec.Evaluate(StoreSeed.Get()); + var stores = spec.Evaluate(StoreSeed.Get()); - stores.Count().Should().Be(take); - stores.OrderBy(x => x.Id).First().Id.Should().Be(11); - stores.OrderBy(x => x.Id).Last().Id.Should().Be(20); - } + stores.Count().Should().Be(take); + stores.OrderBy(x => x.Id).First().Id.Should().Be(11); + stores.OrderBy(x => x.Id).Last().Id.Should().Be(20); + } - [Fact] - public void ReturnsOrderStoresByNameDescForCompanyWithId2_GivenStoresByCompanyOrderedDescByNameSpec() - { - var spec = new StoresByCompanyOrderedDescByNameSpec(2); + [Fact] + public void ReturnsOrderStoresByNameDescForCompanyWithId2_GivenStoresByCompanyOrderedDescByNameSpec() + { + var spec = new StoresByCompanyOrderedDescByNameSpec(2); - var stores = spec.Evaluate(StoreSeed.Get()); + var stores = spec.Evaluate(StoreSeed.Get()); - stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_FIRST_ID); - stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_LAST_ID); - } + stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_FIRST_ID); + stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_LAST_ID); + } - [Fact] - public void ReturnsOrderStoresByNameDescThenByIdForCompanyWithId2_GivenStoresByCompanyOrderedDescByNameThenByIdSpec() - { - var spec = new StoresByCompanyOrderedDescByNameThenByIdSpec(2); + [Fact] + public void ReturnsOrderStoresByNameDescThenByIdForCompanyWithId2_GivenStoresByCompanyOrderedDescByNameThenByIdSpec() + { + var spec = new StoresByCompanyOrderedDescByNameThenByIdSpec(2); - var stores = spec.Evaluate(StoreSeed.Get()); + var stores = spec.Evaluate(StoreSeed.Get()); - stores.First().Id.Should().Be(99); - stores.Last().Id.Should().Be(98); - } + stores.First().Id.Should().Be(99); + stores.Last().Id.Should().Be(98); + } - [Fact] - public void ReturnsSecondPageOfStoresForCompanyWithId2_GivenStoresByCompanyPaginatedOrderedDescByNameSpec() - { - var take = 10; // pagesize 10 - var skip = (2 - 1) * 10; // page 2 + [Fact] + public void ReturnsSecondPageOfStoresForCompanyWithId2_GivenStoresByCompanyPaginatedOrderedDescByNameSpec() + { + var take = 10; // pagesize 10 + var skip = (2 - 1) * 10; // page 2 - var spec = new StoresByCompanyPaginatedOrderedDescByNameSpec(2, skip, take); + var spec = new StoresByCompanyPaginatedOrderedDescByNameSpec(2, skip, take); - var stores = spec.Evaluate(StoreSeed.Get()); + var stores = spec.Evaluate(StoreSeed.Get()); - stores.Count().Should().Be(take); - stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_PAGE2_FIRST_ID); - stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_PAGE2_LAST_ID); - } + stores.Count().Should().Be(take); + stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_PAGE2_FIRST_ID); + stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FOR_COMPANY2_PAGE2_LAST_ID); + } - [Fact] - public void ReturnsSecondPageOfStoresForCompanyWithId2_GivenStoresByCompanyPaginatedSpec() - { - var take = 10; // pagesize 10 - var skip = (2 - 1) * 10; // page 2 + [Fact] + public void ReturnsSecondPageOfStoresForCompanyWithId2_GivenStoresByCompanyPaginatedSpec() + { + var take = 10; // pagesize 10 + var skip = (2 - 1) * 10; // page 2 - var spec = new StoresByCompanyPaginatedSpec(2, skip, take); + var spec = new StoresByCompanyPaginatedSpec(2, skip, take); - var stores = spec.Evaluate(StoreSeed.Get()); + var stores = spec.Evaluate(StoreSeed.Get()); - stores.Count().Should().Be(take); - stores.OrderBy(x => x.Id).First().Id.Should().Be(61); - stores.OrderBy(x => x.Id).Last().Id.Should().Be(70); - } + stores.Count().Should().Be(take); + stores.OrderBy(x => x.Id).First().Id.Should().Be(61); + stores.OrderBy(x => x.Id).Last().Id.Should().Be(70); + } - [Fact] - public void ReturnsOrderedStores_GivenStoresOrderedSpecByName() - { - var spec = new StoresOrderedSpecByName(); + [Fact] + public void ReturnsOrderedStores_GivenStoresOrderedSpecByName() + { + var spec = new StoresOrderedSpecByName(); - var stores = spec.Evaluate(StoreSeed.Get()); + var stores = spec.Evaluate(StoreSeed.Get()); - stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_FIRST_ID); - stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_LAST_ID); - } + stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_FIRST_ID); + stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_LAST_ID); + } - [Fact] - public void ReturnsOrderedStores_GivenStoresOrderedDescendingByNameSpec() - { - var spec = new StoresOrderedDescendingByNameSpec(); + [Fact] + public void ReturnsOrderedStores_GivenStoresOrderedDescendingByNameSpec() + { + var spec = new StoresOrderedDescendingByNameSpec(); - var stores = spec.Evaluate(StoreSeed.Get()); + var stores = spec.Evaluate(StoreSeed.Get()); - stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FIRST_ID); - stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_LAST_ID); - } + stores.First().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_FIRST_ID); + stores.Last().Id.Should().Be(StoreSeed.ORDERED_BY_NAME_DESC_LAST_ID); + } - [Fact] - public void ThrowsDuplicateOrderChainException_GivenSpecWithMultipleOrderChains() - { - var spec = new StoresOrderedTwoChainsSpec(); + [Fact] + public void ThrowsDuplicateOrderChainException_GivenSpecWithMultipleOrderChains() + { + var spec = new StoresOrderedTwoChainsSpec(); - Action sutAction = () => spec.Evaluate(StoreSeed.Get()); + Action sutAction = () => spec.Evaluate(StoreSeed.Get()); - sutAction.Should() - .Throw() - .WithMessage("The specification contains more than one Order chain!"); - } + sutAction.Should() + .Throw() + .WithMessage("The specification contains more than one Order chain!"); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/EvaluatorTests/SearchEvaluator_Evaluate.cs b/Specification/tests/Ardalis.Specification.UnitTests/EvaluatorTests/SearchEvaluator_Evaluate.cs index be03a5ad..9d9da4d3 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/EvaluatorTests/SearchEvaluator_Evaluate.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/EvaluatorTests/SearchEvaluator_Evaluate.cs @@ -4,7 +4,7 @@ namespace Ardalis.Specification.UnitTests; public class SearchEvaluator_Evaluate { - private static readonly List _people = new() + private static readonly List _people = new() { new Person("James"), new Person("Robert"), @@ -14,35 +14,35 @@ public class SearchEvaluator_Evaluate new Person("David"), }; - [Theory] - [InlineData("%mes", 1)] - [InlineData("%r%", 2)] - [InlineData("_inda", 1)] - [InlineData("M%", 2)] - [InlineData("[RM]%", 3)] - [InlineData("_[IA]%", 5)] - public void ReturnsFilteredList_GivenSearchExpression(string searchTerm, int expectedCount) - { - var result = SearchEvaluator.Instance.Evaluate(_people, new PersonSpecification(searchTerm)); + [Theory] + [InlineData("%mes", 1)] + [InlineData("%r%", 2)] + [InlineData("_inda", 1)] + [InlineData("M%", 2)] + [InlineData("[RM]%", 3)] + [InlineData("_[IA]%", 5)] + public void ReturnsFilteredList_GivenSearchExpression(string searchTerm, int expectedCount) + { + var result = SearchEvaluator.Instance.Evaluate(_people, new PersonSpecification(searchTerm)); - result.Should().HaveCount(expectedCount); - } + result.Should().HaveCount(expectedCount); + } } public class PersonSpecification : Specification { - public PersonSpecification(string searchTerm) - { - Query.Search(x => x.Name, searchTerm); - } + public PersonSpecification(string searchTerm) + { + Query.Search(x => x.Name, searchTerm); + } } public class Person { - public string Name { get; } + public string Name { get; } - public Person(string name) - { - Name = name; - } + public Person(string name) + { + Name = name; + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/EvaluatorTests/SearchExtension_Like.cs b/Specification/tests/Ardalis.Specification.UnitTests/EvaluatorTests/SearchExtension_Like.cs index 8162ed58..6c79d78e 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/EvaluatorTests/SearchExtension_Like.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/EvaluatorTests/SearchExtension_Like.cs @@ -4,88 +4,88 @@ namespace Ardalis.Specification.UnitTests.EvaluatorTests; public class SearchExtension_Like { - [Theory] - [InlineData(true, "%", "")] - [InlineData(true, "%", " ")] - [InlineData(true, "%", "asdfa asdf asdf")] - [InlineData(true, "%", "%")] - [InlineData(false, "_", "")] - [InlineData(true, "_", " ")] - [InlineData(true, "_", "4")] - [InlineData(true, "_", "C")] - [InlineData(true, "_", "c")] - [InlineData(false, "_", "CX")] - [InlineData(false, "_", "cx")] - [InlineData(true, "[A]", "a")] - [InlineData(false, "[A]", "ab")] - [InlineData(false, "[ABCD]", "")] - [InlineData(true, "[ABCD]", "A")] - [InlineData(true, "[ABCD]", "b")] - [InlineData(false, "[ABCD]", "X")] - [InlineData(false, "[ABCD]", "AB")] - [InlineData(true, "[B-D]", "C")] - [InlineData(true, "[B-D]", "D")] - [InlineData(false, "[B-D]", "A")] - [InlineData(false, "[^B-D]", "C")] - [InlineData(false, "[^B-D]", "D")] - [InlineData(true, "[^B-D)]", "A")] - [InlineData(true, "%TEST[ABCD]XXX", "lolTESTBXXX")] - [InlineData(false, "%TEST[ABCD]XXX", "lolTESTZXXX")] - [InlineData(false, "%TEST[^ABCD]XXX", "lolTESTBXXX")] - [InlineData(true, "%TEST[^ABCD]XXX", "lolTESTZXXX")] - [InlineData(true, "%TEST[B-D]XXX", "lolTESTBXXX")] - [InlineData(true, "%TEST[^B-D)]XXX", "lolTESTZXXX")] - [InlineData(true, "%Stuff.txt", "Stuff.txt")] - [InlineData(true, "%Stuff.txt", "MagicStuff.txt")] - [InlineData(false, "%Stuff.txt", "MagicStuff.txt.img")] - [InlineData(false, "%Stuff.txt", "Stuff.txt.img")] - [InlineData(false, "%Stuff.txt", "MagicStuff001.txt.img")] - [InlineData(true, "Stuff.txt%", "Stuff.txt")] - [InlineData(false, "Stuff.txt%", "MagicStuff.txt")] - [InlineData(false, "Stuff.txt%", "MagicStuff.txt.img")] - [InlineData(true, "Stuff.txt%", "Stuff.txt.img")] - [InlineData(false, "Stuff.txt%", "MagicStuff001.txt.img")] - [InlineData(true, "%Stuff.txt%", "Stuff.txt")] - [InlineData(true, "%Stuff.txt%", "MagicStuff.txt")] - [InlineData(true, "%Stuff.txt%", "MagicStuff.txt.img")] - [InlineData(true, "%Stuff.txt%", "Stuff.txt.img")] - [InlineData(false, "%Stuff.txt%", "MagicStuff001.txt.img")] - [InlineData(true, "%Stuff%.txt", "Stuff.txt")] - [InlineData(true, "%Stuff%.txt", "MagicStuff.txt")] - [InlineData(false, "%Stuff%.txt", "MagicStuff.txt.img")] - [InlineData(false, "%Stuff%.txt", "Stuff.txt.img")] - [InlineData(false, "%Stuff%.txt", "MagicStuff001.txt.img")] - [InlineData(true, "%Stuff%.txt", "MagicStuff001.txt")] - [InlineData(true, "Stuff%.txt%", "Stuff.txt")] - [InlineData(false, "Stuff%.txt%", "MagicStuff.txt")] - [InlineData(false, "Stuff%.txt%", "MagicStuff.txt.img")] - [InlineData(true, "Stuff%.txt%", "Stuff.txt.img")] - [InlineData(false, "Stuff%.txt%", "MagicStuff001.txt.img")] - [InlineData(false, "Stuff%.txt%", "MagicStuff001.txt")] - [InlineData(true, "%Stuff%.txt%", "Stuff.txt")] - [InlineData(true, "%Stuff%.txt%", "MagicStuff.txt")] - [InlineData(true, "%Stuff%.txt%", "MagicStuff.txt.img")] - [InlineData(true, "%Stuff%.txt%", "Stuff.txt.img")] - [InlineData(true, "%Stuff%.txt%", "MagicStuff001.txt.img")] - [InlineData(true, "%Stuff%.txt%", "MagicStuff001.txt")] - [InlineData(true, "_Stuff_.txt_", "1Stuff3.txt4")] - [InlineData(false, "_Stuff_.txt_", "1Stuff.txt4")] - [InlineData(false, "_Stuff_.txt_", "1Stuff3.txt")] - [InlineData(false, "_Stuff_.txt_", "Stuff3.txt4")] - public void ReturnsExpectedResult_GivenPatternAndInput(bool expectedResult, string pattern, string input) - { - var result = input.Like(pattern); + [Theory] + [InlineData(true, "%", "")] + [InlineData(true, "%", " ")] + [InlineData(true, "%", "asdfa asdf asdf")] + [InlineData(true, "%", "%")] + [InlineData(false, "_", "")] + [InlineData(true, "_", " ")] + [InlineData(true, "_", "4")] + [InlineData(true, "_", "C")] + [InlineData(true, "_", "c")] + [InlineData(false, "_", "CX")] + [InlineData(false, "_", "cx")] + [InlineData(true, "[A]", "a")] + [InlineData(false, "[A]", "ab")] + [InlineData(false, "[ABCD]", "")] + [InlineData(true, "[ABCD]", "A")] + [InlineData(true, "[ABCD]", "b")] + [InlineData(false, "[ABCD]", "X")] + [InlineData(false, "[ABCD]", "AB")] + [InlineData(true, "[B-D]", "C")] + [InlineData(true, "[B-D]", "D")] + [InlineData(false, "[B-D]", "A")] + [InlineData(false, "[^B-D]", "C")] + [InlineData(false, "[^B-D]", "D")] + [InlineData(true, "[^B-D)]", "A")] + [InlineData(true, "%TEST[ABCD]XXX", "lolTESTBXXX")] + [InlineData(false, "%TEST[ABCD]XXX", "lolTESTZXXX")] + [InlineData(false, "%TEST[^ABCD]XXX", "lolTESTBXXX")] + [InlineData(true, "%TEST[^ABCD]XXX", "lolTESTZXXX")] + [InlineData(true, "%TEST[B-D]XXX", "lolTESTBXXX")] + [InlineData(true, "%TEST[^B-D)]XXX", "lolTESTZXXX")] + [InlineData(true, "%Stuff.txt", "Stuff.txt")] + [InlineData(true, "%Stuff.txt", "MagicStuff.txt")] + [InlineData(false, "%Stuff.txt", "MagicStuff.txt.img")] + [InlineData(false, "%Stuff.txt", "Stuff.txt.img")] + [InlineData(false, "%Stuff.txt", "MagicStuff001.txt.img")] + [InlineData(true, "Stuff.txt%", "Stuff.txt")] + [InlineData(false, "Stuff.txt%", "MagicStuff.txt")] + [InlineData(false, "Stuff.txt%", "MagicStuff.txt.img")] + [InlineData(true, "Stuff.txt%", "Stuff.txt.img")] + [InlineData(false, "Stuff.txt%", "MagicStuff001.txt.img")] + [InlineData(true, "%Stuff.txt%", "Stuff.txt")] + [InlineData(true, "%Stuff.txt%", "MagicStuff.txt")] + [InlineData(true, "%Stuff.txt%", "MagicStuff.txt.img")] + [InlineData(true, "%Stuff.txt%", "Stuff.txt.img")] + [InlineData(false, "%Stuff.txt%", "MagicStuff001.txt.img")] + [InlineData(true, "%Stuff%.txt", "Stuff.txt")] + [InlineData(true, "%Stuff%.txt", "MagicStuff.txt")] + [InlineData(false, "%Stuff%.txt", "MagicStuff.txt.img")] + [InlineData(false, "%Stuff%.txt", "Stuff.txt.img")] + [InlineData(false, "%Stuff%.txt", "MagicStuff001.txt.img")] + [InlineData(true, "%Stuff%.txt", "MagicStuff001.txt")] + [InlineData(true, "Stuff%.txt%", "Stuff.txt")] + [InlineData(false, "Stuff%.txt%", "MagicStuff.txt")] + [InlineData(false, "Stuff%.txt%", "MagicStuff.txt.img")] + [InlineData(true, "Stuff%.txt%", "Stuff.txt.img")] + [InlineData(false, "Stuff%.txt%", "MagicStuff001.txt.img")] + [InlineData(false, "Stuff%.txt%", "MagicStuff001.txt")] + [InlineData(true, "%Stuff%.txt%", "Stuff.txt")] + [InlineData(true, "%Stuff%.txt%", "MagicStuff.txt")] + [InlineData(true, "%Stuff%.txt%", "MagicStuff.txt.img")] + [InlineData(true, "%Stuff%.txt%", "Stuff.txt.img")] + [InlineData(true, "%Stuff%.txt%", "MagicStuff001.txt.img")] + [InlineData(true, "%Stuff%.txt%", "MagicStuff001.txt")] + [InlineData(true, "_Stuff_.txt_", "1Stuff3.txt4")] + [InlineData(false, "_Stuff_.txt_", "1Stuff.txt4")] + [InlineData(false, "_Stuff_.txt_", "1Stuff3.txt")] + [InlineData(false, "_Stuff_.txt_", "Stuff3.txt4")] + public void ReturnsExpectedResult_GivenPatternAndInput(bool expectedResult, string pattern, string input) + { + var result = input.Like(pattern); - result.Should().Be(expectedResult); - } + result.Should().Be(expectedResult); + } - [Theory] - [InlineData("[", "asd")] - [InlineData("[]", "asd")] - public void ShouldThrowInvalidSearchPattern_GivenInvalidPattern(string pattern, string input) - { - Action action = () => input.Like(pattern); + [Theory] + [InlineData("[", "asd")] + [InlineData("[]", "asd")] + public void ShouldThrowInvalidSearchPattern_GivenInvalidPattern(string pattern, string input) + { + Action action = () => input.Like(pattern); - action.Should().Throw().WithMessage($"Invalid search pattern: {pattern}"); - } + action.Should().Throw().WithMessage($"Invalid search pattern: {pattern}"); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/ConcurrentSelectorsExceptionTests.cs b/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/ConcurrentSelectorsExceptionTests.cs index c3bc6472..9c81ce3c 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/ConcurrentSelectorsExceptionTests.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/ConcurrentSelectorsExceptionTests.cs @@ -4,22 +4,22 @@ namespace Ardalis.Specification.UnitTests; public class ConcurrentSelectorsExceptionTests { - private const string _defaultMessage = "Concurrent specification selector transforms defined. Ensure only one of the Select() or SelectMany() transforms is used in the same specification!"; + private const string _defaultMessage = "Concurrent specification selector transforms defined. Ensure only one of the Select() or SelectMany() transforms is used in the same specification!"; - [Fact] - public void ThrowWithDefaultConstructor() - { - Action action = () => throw new ConcurrentSelectorsException(); + [Fact] + public void ThrowWithDefaultConstructor() + { + Action action = () => throw new ConcurrentSelectorsException(); - action.Should().Throw().WithMessage(_defaultMessage); - } + action.Should().Throw().WithMessage(_defaultMessage); + } - [Fact] - public void ThrowWithInnerException() - { - var inner = new Exception("test"); - Action action = () => throw new ConcurrentSelectorsException(inner); + [Fact] + public void ThrowWithInnerException() + { + var inner = new Exception("test"); + Action action = () => throw new ConcurrentSelectorsException(inner); - action.Should().Throw().WithMessage(_defaultMessage).WithInnerException().WithMessage("test"); - } + action.Should().Throw().WithMessage(_defaultMessage).WithInnerException().WithMessage("test"); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/DuplicateOrderChainExceptionTests.cs b/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/DuplicateOrderChainExceptionTests.cs index f4294acb..7b3555c8 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/DuplicateOrderChainExceptionTests.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/DuplicateOrderChainExceptionTests.cs @@ -4,22 +4,22 @@ namespace Ardalis.Specification.UnitTests; public class DuplicateOrderChainExceptionTests { - private const string _defaultMessage = "The specification contains more than one Order chain!"; + private const string _defaultMessage = "The specification contains more than one Order chain!"; - [Fact] - public void ThrowWithDefaultConstructor() - { - Action action = () => throw new DuplicateOrderChainException(); + [Fact] + public void ThrowWithDefaultConstructor() + { + Action action = () => throw new DuplicateOrderChainException(); - action.Should().Throw().WithMessage(_defaultMessage); - } + action.Should().Throw().WithMessage(_defaultMessage); + } - [Fact] - public void ThrowWithInnerException() - { - var inner = new Exception("test"); - Action action = () => throw new DuplicateOrderChainException(inner); + [Fact] + public void ThrowWithInnerException() + { + var inner = new Exception("test"); + Action action = () => throw new DuplicateOrderChainException(inner); - action.Should().Throw().WithMessage(_defaultMessage).WithInnerException().WithMessage("test"); - } + action.Should().Throw().WithMessage(_defaultMessage).WithInnerException().WithMessage("test"); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/DuplicateSkipExceptionTests.cs b/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/DuplicateSkipExceptionTests.cs index 92477a85..e3955abf 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/DuplicateSkipExceptionTests.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/DuplicateSkipExceptionTests.cs @@ -4,22 +4,22 @@ namespace Ardalis.Specification.UnitTests; public class DuplicateSkipExceptionTests { - private const string _defaultMessage = "Duplicate use of Skip(). Ensure you don't use Skip() more than once in the same specification!"; + private const string _defaultMessage = "Duplicate use of Skip(). Ensure you don't use Skip() more than once in the same specification!"; - [Fact] - public void ThrowWithDefaultConstructor() - { - Action action = () => throw new DuplicateSkipException(); + [Fact] + public void ThrowWithDefaultConstructor() + { + Action action = () => throw new DuplicateSkipException(); - action.Should().Throw().WithMessage(_defaultMessage); - } + action.Should().Throw().WithMessage(_defaultMessage); + } - [Fact] - public void ThrowWithInnerException() - { - var inner = new Exception("test"); - Action action = () => throw new DuplicateSkipException(inner); + [Fact] + public void ThrowWithInnerException() + { + var inner = new Exception("test"); + Action action = () => throw new DuplicateSkipException(inner); - action.Should().Throw().WithMessage(_defaultMessage).WithInnerException().WithMessage("test"); - } + action.Should().Throw().WithMessage(_defaultMessage).WithInnerException().WithMessage("test"); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/DuplicateTakeExceptionTests.cs b/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/DuplicateTakeExceptionTests.cs index fafebaab..5dc9c0bc 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/DuplicateTakeExceptionTests.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/DuplicateTakeExceptionTests.cs @@ -4,22 +4,22 @@ namespace Ardalis.Specification.UnitTests; public class DuplicateTakeExceptionTests { - private const string _defaultMessage = "Duplicate use of Take(). Ensure you don't use Take() more than once in the same specification!"; + private const string _defaultMessage = "Duplicate use of Take(). Ensure you don't use Take() more than once in the same specification!"; - [Fact] - public void ThrowWithDefaultConstructor() - { - Action action = () => throw new DuplicateTakeException(); + [Fact] + public void ThrowWithDefaultConstructor() + { + Action action = () => throw new DuplicateTakeException(); - action.Should().Throw().WithMessage(_defaultMessage); - } + action.Should().Throw().WithMessage(_defaultMessage); + } - [Fact] - public void ThrowWithInnerException() - { - var inner = new Exception("test"); - Action action = () => throw new DuplicateTakeException(inner); + [Fact] + public void ThrowWithInnerException() + { + var inner = new Exception("test"); + Action action = () => throw new DuplicateTakeException(inner); - action.Should().Throw().WithMessage(_defaultMessage).WithInnerException().WithMessage("test"); - } + action.Should().Throw().WithMessage(_defaultMessage).WithInnerException().WithMessage("test"); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/InvalidSearchPatternExceptionTests.cs b/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/InvalidSearchPatternExceptionTests.cs index 3ca556a9..4a28fdef 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/InvalidSearchPatternExceptionTests.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/InvalidSearchPatternExceptionTests.cs @@ -4,23 +4,23 @@ namespace Ardalis.Specification.UnitTests; public class InvalidSearchPatternExceptionTests { - private const string _defaultMessage = "Invalid search pattern: " + _pattern; - private const string _pattern = "x"; + private const string _defaultMessage = "Invalid search pattern: " + _pattern; + private const string _pattern = "x"; - [Fact] - public void ThrowWithDefaultConstructor() - { - Action action = () => throw new InvalidSearchPatternException(_pattern); + [Fact] + public void ThrowWithDefaultConstructor() + { + Action action = () => throw new InvalidSearchPatternException(_pattern); - action.Should().Throw(_pattern).WithMessage(_defaultMessage); - } + action.Should().Throw(_pattern).WithMessage(_defaultMessage); + } - [Fact] - public void ThrowWithInnerException() - { - var inner = new Exception("test"); - Action action = () => throw new InvalidSearchPatternException(_pattern, inner); + [Fact] + public void ThrowWithInnerException() + { + var inner = new Exception("test"); + Action action = () => throw new InvalidSearchPatternException(_pattern, inner); - action.Should().Throw(_pattern).WithMessage(_defaultMessage).WithInnerException().WithMessage("test"); - } + action.Should().Throw(_pattern).WithMessage(_defaultMessage).WithInnerException().WithMessage("test"); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/SelectorNotFoundExceptionTests.cs b/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/SelectorNotFoundExceptionTests.cs index 72e9b39d..5a4aec05 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/SelectorNotFoundExceptionTests.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/ExceptionTests/SelectorNotFoundExceptionTests.cs @@ -4,22 +4,22 @@ namespace Ardalis.Specification.UnitTests; public class SelectorNotFoundExceptionTests { - private const string _defaultMessage = "The specification must have a selector transform defined. Ensure either Select() or SelectMany() is used in the specification!"; + private const string _defaultMessage = "The specification must have a selector transform defined. Ensure either Select() or SelectMany() is used in the specification!"; - [Fact] - public void ThrowWithDefaultConstructor() - { - Action action = () => throw new SelectorNotFoundException(); + [Fact] + public void ThrowWithDefaultConstructor() + { + Action action = () => throw new SelectorNotFoundException(); - action.Should().Throw().WithMessage(_defaultMessage); - } + action.Should().Throw().WithMessage(_defaultMessage); + } - [Fact] - public void ThrowWithInnerException() - { - var inner = new Exception("test"); - Action action = () => throw new SelectorNotFoundException(inner); + [Fact] + public void ThrowWithInnerException() + { + var inner = new Exception("test"); + Action action = () => throw new SelectorNotFoundException(inner); - action.Should().Throw().WithMessage(_defaultMessage).WithInnerException().WithMessage("test"); - } + action.Should().Throw().WithMessage(_defaultMessage).WithInnerException().WithMessage("test"); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Address.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Address.cs index 1b197d7c..93b8763e 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Address.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Address.cs @@ -2,14 +2,14 @@ public class Address { - public int Id { get; set; } - public string? Street { get; set; } + public int Id { get; set; } + public string? Street { get; set; } - public int StoreId { get; set; } - public Store? Store { get; set; } + public int StoreId { get; set; } + public Store? Store { get; set; } - public object GetSomethingFromAddress() - { - return new object(); - } + public object GetSomethingFromAddress() + { + return new object(); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Company.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Company.cs index 5b384393..f4dd0588 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Company.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Company.cs @@ -4,11 +4,11 @@ namespace Ardalis.Specification.UnitTests.Fixture.Entities; public class Company { - public int Id { get; set; } - public string? Name { get; set; } + public int Id { get; set; } + public string? Name { get; set; } - public int CountryId { get; set; } - public Country? Country { get; set; } + public int CountryId { get; set; } + public Country? Country { get; set; } - public List Stores { get; set; } = new List(); + public List Stores { get; set; } = new List(); } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Country.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Country.cs index 2ec5b0c8..0a778f4a 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Country.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Country.cs @@ -4,8 +4,8 @@ namespace Ardalis.Specification.UnitTests.Fixture.Entities; public class Country { - public int Id { get; set; } - public string? Name { get; set; } + public int Id { get; set; } + public string? Name { get; set; } - public List Companies { get; set; } = new List(); + public List Companies { get; set; } = new List(); } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Product.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Product.cs index e055b0b6..bc78bf00 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Product.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Product.cs @@ -2,9 +2,9 @@ public class Product { - public int Id { get; set; } - public string? Name { get; set; } + public int Id { get; set; } + public string? Name { get; set; } - public int StoreId { get; set; } - public Store? Store { get; set; } + public int StoreId { get; set; } + public Store? Store { get; set; } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Seeds/AddressSeed.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Seeds/AddressSeed.cs index 03a8e6ab..c5cdfc2b 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Seeds/AddressSeed.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Seeds/AddressSeed.cs @@ -5,23 +5,23 @@ namespace Ardalis.Specification.UnitTests.Fixture.Entities.Seeds; public class AddressSeed { #pragma warning disable IDE1006 // Naming Styles - public const string VALID_STREET_FOR_STOREID1 = "Street 1"; + public const string VALID_STREET_FOR_STOREID1 = "Street 1"; #pragma warning restore IDE1006 // Naming Styles - public static List
Get() - { - var addresses = new List
(); - - for (var i = 1; i <= 100; i++) + public static List
Get() { - addresses.Add(new Address() - { - Id = i, - Street = $"Street {i}", - StoreId = i - }); - } + var addresses = new List
(); - return addresses; - } + for (var i = 1; i <= 100; i++) + { + addresses.Add(new Address() + { + Id = i, + Street = $"Street {i}", + StoreId = i + }); + } + + return addresses; + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Seeds/CompanySeed.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Seeds/CompanySeed.cs index c19853e7..b38c6bf9 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Seeds/CompanySeed.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Seeds/CompanySeed.cs @@ -5,13 +5,13 @@ namespace Ardalis.Specification.UnitTests.Fixture.Entities.Seeds; public class CompanySeed { #pragma warning disable IDE1006 // Naming Styles - public const int VALID_COMPANY_ID = 1; - public const string VALID_COMPANY_NAME = "Company 1"; + public const int VALID_COMPANY_ID = 1; + public const string VALID_COMPANY_NAME = "Company 1"; #pragma warning restore IDE1006 // Naming Styles - public static List Get() - { - var companies = new List + public static List Get() + { + var companies = new List { new Company() { @@ -35,6 +35,6 @@ public static List Get() } }; - return companies; - } + return companies; + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Seeds/CountrySeed.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Seeds/CountrySeed.cs index f83c48c7..084d161c 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Seeds/CountrySeed.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Seeds/CountrySeed.cs @@ -4,22 +4,22 @@ namespace Ardalis.Specification.UnitTests.Fixture.Entities.Seeds; public class CountrySeed { - public static List Get() - { - var countries = new List(); - - countries.Add(new Country() + public static List Get() { - Id = 1, - Name = "Country 1", - }); + var countries = new List(); - countries.Add(new Country() - { - Id = 2, - Name = "Country 2", - }); + countries.Add(new Country() + { + Id = 1, + Name = "Country 1", + }); + + countries.Add(new Country() + { + Id = 2, + Name = "Country 2", + }); - return countries; - } + return countries; + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Seeds/ProductSeed.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Seeds/ProductSeed.cs index 54b1a83d..2c75ae09 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Seeds/ProductSeed.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Seeds/ProductSeed.cs @@ -5,30 +5,30 @@ namespace Ardalis.Specification.UnitTests.Fixture.Entities.Seeds; public class ProductSeed { #pragma warning disable IDE1006 // Naming Styles - public const int TOTAL_PRODUCT_COUNT = 100; - public const string VALID_PRODUCT_NAME = "Product 1"; + public const int TOTAL_PRODUCT_COUNT = 100; + public const string VALID_PRODUCT_NAME = "Product 1"; #pragma warning restore IDE1006 // Naming Styles - public static List Get() - { - var products = new List(); - - for (var i = 1; i < TOTAL_PRODUCT_COUNT; i += 2) + public static List Get() { - products.Add(new Product() - { - Id = i, - Name = $"Product {i}", - StoreId = i, - }); - products.Add(new Product() - { - Id = i + 1, - Name = $"Product {i + 1}", - StoreId = i, - }); - } + var products = new List(); - return products; - } + for (var i = 1; i < TOTAL_PRODUCT_COUNT; i += 2) + { + products.Add(new Product() + { + Id = i, + Name = $"Product {i}", + StoreId = i, + }); + products.Add(new Product() + { + Id = i + 1, + Name = $"Product {i + 1}", + StoreId = i, + }); + } + + return products; + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Seeds/StoreSeed.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Seeds/StoreSeed.cs index 842f942b..b5f2f180 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Seeds/StoreSeed.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Seeds/StoreSeed.cs @@ -5,71 +5,71 @@ namespace Ardalis.Specification.UnitTests.Fixture.Entities.Seeds; public class StoreSeed { #pragma warning disable IDE1006 // Naming Styles - public const int VALID_STORE_ID = 1; - public const string VALID_STORE_NAME = "Store 1"; - public const string VALID_STORE_City = "City 1"; + public const int VALID_STORE_ID = 1; + public const string VALID_STORE_NAME = "Store 1"; + public const string VALID_STORE_City = "City 1"; - public const int VALID_Search_ID = 50; - public const string VALID_Search_City_Key = "BCD"; - public const string VALID_Search_Name_Key = "BCE"; - public const string VALID_Search_City_Name_Key = "BC"; + public const int VALID_Search_ID = 50; + public const string VALID_Search_City_Key = "BCD"; + public const string VALID_Search_Name_Key = "BCE"; + public const string VALID_Search_City_Name_Key = "BC"; - public const int ORDERED_BY_NAME_FIRST_ID = 48; - public const int ORDERED_BY_NAME_LAST_ID = 49; - public const int ORDERED_BY_NAME_DESC_FIRST_ID = 49; - public const int ORDERED_BY_NAME_DESC_LAST_ID = 48; + public const int ORDERED_BY_NAME_FIRST_ID = 48; + public const int ORDERED_BY_NAME_LAST_ID = 49; + public const int ORDERED_BY_NAME_DESC_FIRST_ID = 49; + public const int ORDERED_BY_NAME_DESC_LAST_ID = 48; - public const int ORDERED_BY_NAME_FOR_COMPANY2_FIRST_ID = 98; - public const int ORDERED_BY_NAME_FOR_COMPANY2_LAST_ID = 99; - public const int ORDERED_BY_NAME_DESC_FOR_COMPANY2_FIRST_ID = 99; - public const int ORDERED_BY_NAME_DESC_FOR_COMPANY2_LAST_ID = 98; - public const int ORDERED_BY_NAME_DESC_FOR_COMPANY2_PAGE2_FIRST_ID = 89; - public const int ORDERED_BY_NAME_DESC_FOR_COMPANY2_PAGE2_LAST_ID = 80; + public const int ORDERED_BY_NAME_FOR_COMPANY2_FIRST_ID = 98; + public const int ORDERED_BY_NAME_FOR_COMPANY2_LAST_ID = 99; + public const int ORDERED_BY_NAME_DESC_FOR_COMPANY2_FIRST_ID = 99; + public const int ORDERED_BY_NAME_DESC_FOR_COMPANY2_LAST_ID = 98; + public const int ORDERED_BY_NAME_DESC_FOR_COMPANY2_PAGE2_FIRST_ID = 89; + public const int ORDERED_BY_NAME_DESC_FOR_COMPANY2_PAGE2_LAST_ID = 80; #pragma warning restore IDE1006 // Naming Styles - public static List Get() - { - var stores = new List(); - - for (var i = 1; i <= 50; i++) - { - stores.Add(new Store() - { - Id = i, - Name = $"Store {i}", - City = $"City {i}", - AddressId = i, - CompanyId = 1, - }); - } - for (var i = 51; i <= 100; i++) + public static List Get() { - stores.Add(new Store() - { - Id = i, - Name = $"Store {i}", - City = $"City {i}", - AddressId = i, - CompanyId = 2, - }); - } + var stores = new List(); - stores[49 - 1].Name = "ZZZ"; - stores[48 - 1].Name = "AAA"; - stores[99 - 1].Name = "YYY"; - stores[98 - 1].Name = "BBB"; + for (var i = 1; i <= 50; i++) + { + stores.Add(new Store() + { + Id = i, + Name = $"Store {i}", + City = $"City {i}", + AddressId = i, + CompanyId = 1, + }); + } + for (var i = 51; i <= 100; i++) + { + stores.Add(new Store() + { + Id = i, + Name = $"Store {i}", + City = $"City {i}", + AddressId = i, + CompanyId = 2, + }); + } - stores[100 - 1].Name = "Store 999"; + stores[49 - 1].Name = "ZZZ"; + stores[48 - 1].Name = "AAA"; + stores[99 - 1].Name = "YYY"; + stores[98 - 1].Name = "BBB"; - stores[50 - 1].City = "ABCDEFGH"; - stores[50 - 1].Name = "ABCEFGH"; + stores[100 - 1].Name = "Store 999"; - return stores; - } + stores[50 - 1].City = "ABCDEFGH"; + stores[50 - 1].Name = "ABCEFGH"; - internal static IQueryable AsQueryable() - { - return Get().AsQueryable(); - } + return stores; + } + + internal static IQueryable AsQueryable() + { + return Get().AsQueryable(); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Store.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Store.cs index 24373c4d..29e4b3b0 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Store.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Entities/Store.cs @@ -4,20 +4,20 @@ namespace Ardalis.Specification.UnitTests.Fixture.Entities; public class Store { - public int Id { get; set; } - public string? Name { get; set; } - public string? City { get; set; } + public int Id { get; set; } + public string? Name { get; set; } + public string? City { get; set; } - public int CompanyId { get; set; } - public Company? Company { get; set; } + public int CompanyId { get; set; } + public Company? Company { get; set; } - public int AddressId { get; set; } - public Address? Address { get; set; } + public int AddressId { get; set; } + public Address? Address { get; set; } - public List Products { get; set; } = new List(); + public List Products { get; set; } = new List(); - public static object GetSomethingFromStore() - { - return new object(); - } + public static object GetSomethingFromStore() + { + return new object(); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdAsSplitQuery.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdAsSplitQuery.cs index 5b8b630e..7bf8fa03 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdAsSplitQuery.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdAsSplitQuery.cs @@ -2,11 +2,11 @@ public class CompanyByIdAsSplitQuery : Specification, ISingleResultSpecification { - public CompanyByIdAsSplitQuery(int id) - { - Query.Where(company => company.Id == id) - .Include(x => x.Stores) - .ThenInclude(x => x.Products) - .AsSplitQuery(); - } + public CompanyByIdAsSplitQuery(int id) + { + Query.Where(company => company.Id == id) + .Include(x => x.Stores) + .ThenInclude(x => x.Products) + .AsSplitQuery(); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdAsTrackedSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdAsTrackedSpec.cs index e0914e95..9775a9bd 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdAsTrackedSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdAsTrackedSpec.cs @@ -2,8 +2,8 @@ public class CompanyByIdAsTrackedSpec : Specification, ISingleResultSpecification { - public CompanyByIdAsTrackedSpec(int id) - { - Query.Where(company => company.Id == id).AsTracking(); - } + public CompanyByIdAsTrackedSpec(int id) + { + Query.Where(company => company.Id == id).AsTracking(); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdAsUntrackedSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdAsUntrackedSpec.cs index 5d884f6d..362a76ae 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdAsUntrackedSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdAsUntrackedSpec.cs @@ -2,8 +2,8 @@ public class CompanyByIdAsUntrackedSpec : Specification, ISingleResultSpecification { - public CompanyByIdAsUntrackedSpec(int id) - { - Query.Where(company => company.Id == id).AsNoTracking(); - } + public CompanyByIdAsUntrackedSpec(int id) + { + Query.Where(company => company.Id == id).AsNoTracking(); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdAsUntrackedWithIdentityResolutionSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdAsUntrackedWithIdentityResolutionSpec.cs index 39167e2e..26e73bdd 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdAsUntrackedWithIdentityResolutionSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdAsUntrackedWithIdentityResolutionSpec.cs @@ -2,8 +2,8 @@ public class CompanyByIdAsUntrackedWithIdentityResolutionSpec : Specification, ISingleResultSpecification { - public CompanyByIdAsUntrackedWithIdentityResolutionSpec(int id) - { - Query.Where(company => company.Id == id).AsNoTrackingWithIdentityResolution(); - } + public CompanyByIdAsUntrackedWithIdentityResolutionSpec(int id) + { + Query.Where(company => company.Id == id).AsNoTrackingWithIdentityResolution(); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdIgnoreQueryFilters.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdIgnoreQueryFilters.cs index bcc6b731..84107c8b 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdIgnoreQueryFilters.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdIgnoreQueryFilters.cs @@ -2,8 +2,8 @@ public class CompanyByIdIgnoreQueryFilters : Specification, ISingleResultSpecification { - public CompanyByIdIgnoreQueryFilters(int id) - { - Query.Where(company => company.Id == id).IgnoreQueryFilters(); - } + public CompanyByIdIgnoreQueryFilters(int id) + { + Query.Where(company => company.Id == id).IgnoreQueryFilters(); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdIncludeStoresThenIncludeAddressSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdIncludeStoresThenIncludeAddressSpec.cs index 7f581b2f..00136d09 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdIncludeStoresThenIncludeAddressSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdIncludeStoresThenIncludeAddressSpec.cs @@ -2,10 +2,10 @@ public class CompanyByIdIncludeStoresThenIncludeAddressSpec : Specification, ISingleResultSpecification { - public CompanyByIdIncludeStoresThenIncludeAddressSpec(int id) - { - Query.Where(x => x.Id == id) - .Include(x => x.Stores) - .ThenInclude(x => x.Address); - } + public CompanyByIdIncludeStoresThenIncludeAddressSpec(int id) + { + Query.Where(x => x.Id == id) + .Include(x => x.Stores) + .ThenInclude(x => x.Address); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdIncludeStoresThenIncludeProductsSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdIncludeStoresThenIncludeProductsSpec.cs index 03105a93..5e492a84 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdIncludeStoresThenIncludeProductsSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdIncludeStoresThenIncludeProductsSpec.cs @@ -2,10 +2,10 @@ public class CompanyByIdIncludeStoresThenIncludeProductsSpec : Specification, ISingleResultSpecification { - public CompanyByIdIncludeStoresThenIncludeProductsSpec(int id) - { - Query.Where(x => x.Id == id) - .Include(x => x.Stores) - .ThenInclude(x => x.Products); - } + public CompanyByIdIncludeStoresThenIncludeProductsSpec(int id) + { + Query.Where(x => x.Id == id) + .Include(x => x.Stores) + .ThenInclude(x => x.Products); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdSpec.cs index 83339033..4e3b3123 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdSpec.cs @@ -2,8 +2,8 @@ public class CompanyByIdSpec : Specification, ISingleResultSpecification { - public CompanyByIdSpec(int id) - { - Query.Where(company => company.Id == id); - } + public CompanyByIdSpec(int id) + { + Query.Where(company => company.Id == id); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdWithAsNoTrackingAsTrackedSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdWithAsNoTrackingAsTrackedSpec.cs index 79a46ea6..5b08268e 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdWithAsNoTrackingAsTrackedSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdWithAsNoTrackingAsTrackedSpec.cs @@ -2,8 +2,8 @@ public class CompanyByIdWithAsNoTrackingAsTrackedSpec : Specification, ISingleResultSpecification { - public CompanyByIdWithAsNoTrackingAsTrackedSpec(int id) - { - Query.Where(company => company.Id == id).AsNoTracking().AsNoTrackingWithIdentityResolution().AsTracking(); - } + public CompanyByIdWithAsNoTrackingAsTrackedSpec(int id) + { + Query.Where(company => company.Id == id).AsNoTracking().AsNoTrackingWithIdentityResolution().AsTracking(); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdWithAsTrackingAsUntrackedSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdWithAsTrackingAsUntrackedSpec.cs index c7a5ca52..a7db5988 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdWithAsTrackingAsUntrackedSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdWithAsTrackingAsUntrackedSpec.cs @@ -2,8 +2,8 @@ public class CompanyByIdWithAsTrackingAsUntrackedSpec : Specification, ISingleResultSpecification { - public CompanyByIdWithAsTrackingAsUntrackedSpec(int id) - { - Query.Where(company => company.Id == id).AsTracking().AsNoTracking(); - } + public CompanyByIdWithAsTrackingAsUntrackedSpec(int id) + { + Query.Where(company => company.Id == id).AsTracking().AsNoTracking(); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdWithAsTrackingAsUntrackedWithIdentityResolutionSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdWithAsTrackingAsUntrackedWithIdentityResolutionSpec.cs index aeeebb7e..1427bf25 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdWithAsTrackingAsUntrackedWithIdentityResolutionSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdWithAsTrackingAsUntrackedWithIdentityResolutionSpec.cs @@ -3,8 +3,8 @@ public class CompanyByIdWithAsTrackingAsUntrackedWithIdentityResolutionSpec : Specification, ISingleResultSpecification { - public CompanyByIdWithAsTrackingAsUntrackedWithIdentityResolutionSpec(int id) - { - Query.Where(company => company.Id == id).AsTracking().AsNoTrackingWithIdentityResolution(); - } + public CompanyByIdWithAsTrackingAsUntrackedWithIdentityResolutionSpec(int id) + { + Query.Where(company => company.Id == id).AsTracking().AsNoTrackingWithIdentityResolution(); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdWithFalseConditions.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdWithFalseConditions.cs index b6a2a2d5..6b6af030 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdWithFalseConditions.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdWithFalseConditions.cs @@ -2,25 +2,25 @@ public class CompanyByIdWithFalseConditions : Specification, ISingleResultSpecification { - public CompanyByIdWithFalseConditions(int id) - { - Query.Where(x => x.Id == id, false) - .OrderBy(x => x.Id, false) - .ThenBy(x => x.Name) - .ThenByDescending(x => x.Name) - .OrderByDescending(x => x.Id, false) - .ThenBy(x => x.Name) - .ThenByDescending(x => x.Name) - .Include(x => x.Stores, false) - .ThenInclude(x => x.Products) - .Include(nameof(Store), false) - .Take(10, false) - .Skip(10, false) - .AsNoTracking(false) - .AsNoTrackingWithIdentityResolution(false) - .AsSplitQuery(false) - .IgnoreQueryFilters(false) - .Search(x => x.Name!, "asd", false) - .EnableCache(nameof(CompanyByIdWithFalseConditions), false, id); - } + public CompanyByIdWithFalseConditions(int id) + { + Query.Where(x => x.Id == id, false) + .OrderBy(x => x.Id, false) + .ThenBy(x => x.Name) + .ThenByDescending(x => x.Name) + .OrderByDescending(x => x.Id, false) + .ThenBy(x => x.Name) + .ThenByDescending(x => x.Name) + .Include(x => x.Stores, false) + .ThenInclude(x => x.Products) + .Include(nameof(Store), false) + .Take(10, false) + .Skip(10, false) + .AsNoTracking(false) + .AsNoTrackingWithIdentityResolution(false) + .AsSplitQuery(false) + .IgnoreQueryFilters(false) + .Search(x => x.Name!, "asd", false) + .EnableCache(nameof(CompanyByIdWithFalseConditions), false, id); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdWithFalseConditionsForInnerChains.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdWithFalseConditionsForInnerChains.cs index 8b1d58eb..196a8c96 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdWithFalseConditionsForInnerChains.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/CompanyByIdWithFalseConditionsForInnerChains.cs @@ -2,26 +2,26 @@ public class CompanyByIdWithFalseConditionsForInnerChains : Specification, ISingleResultSpecification { - public CompanyByIdWithFalseConditionsForInnerChains(int id) - { - Query.Where(x => x.Id == id, false) - .OrderBy(x => x.Id) - .ThenBy(x => x.Name, false) - .ThenByDescending(x => x.Name) - .OrderByDescending(x => x.Id) - .ThenByDescending(x => x.Name, false) - .ThenBy(x => x.Name) - .Include(x => x.Stores) - .ThenInclude(x => x.Products, false) - .ThenInclude(x => x.Store) - .Include(nameof(Store), false) - .Take(10, false) - .Skip(10, false) - .AsNoTracking(false) - .AsNoTrackingWithIdentityResolution(false) - .AsSplitQuery(false) - .IgnoreQueryFilters(false) - .Search(x => x.Name!, "asd", false) - .EnableCache(nameof(CompanyByIdWithFalseConditions), false, id); - } + public CompanyByIdWithFalseConditionsForInnerChains(int id) + { + Query.Where(x => x.Id == id, false) + .OrderBy(x => x.Id) + .ThenBy(x => x.Name, false) + .ThenByDescending(x => x.Name) + .OrderByDescending(x => x.Id) + .ThenByDescending(x => x.Name, false) + .ThenBy(x => x.Name) + .Include(x => x.Stores) + .ThenInclude(x => x.Products, false) + .ThenInclude(x => x.Store) + .Include(nameof(Store), false) + .Take(10, false) + .Skip(10, false) + .AsNoTracking(false) + .AsNoTrackingWithIdentityResolution(false) + .AsSplitQuery(false) + .IgnoreQueryFilters(false) + .Search(x => x.Name!, "asd", false) + .EnableCache(nameof(CompanyByIdWithFalseConditions), false, id); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdAndNameSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdAndNameSpec.cs index f6b4b533..febc3719 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdAndNameSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdAndNameSpec.cs @@ -2,9 +2,9 @@ public class StoreByIdAndNameSpec : Specification { - public StoreByIdAndNameSpec(int id, string name) - { - Query.Where(x => x.Id == id) - .Where(x => x.Name == name); - } + public StoreByIdAndNameSpec(int id, string name) + { + Query.Where(x => x.Id == id) + .Where(x => x.Name == name); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdIncludeAddressAndProductsSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdIncludeAddressAndProductsSpec.cs index c45ae556..48f88a45 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdIncludeAddressAndProductsSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdIncludeAddressAndProductsSpec.cs @@ -2,10 +2,10 @@ public class StoreByIdIncludeAddressAndProductsSpec : Specification, ISingleResultSpecification { - public StoreByIdIncludeAddressAndProductsSpec(int id) - { - Query.Where(x => x.Id == id); - Query.Include(x => x.Address); - Query.Include(x => x.Products); - } + public StoreByIdIncludeAddressAndProductsSpec(int id) + { + Query.Where(x => x.Id == id); + Query.Include(x => x.Address); + Query.Include(x => x.Products); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdIncludeAddressSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdIncludeAddressSpec.cs index d8eecff1..b3d2be23 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdIncludeAddressSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdIncludeAddressSpec.cs @@ -2,9 +2,9 @@ public class StoreByIdIncludeAddressSpec : Specification, ISingleResultSpecification { - public StoreByIdIncludeAddressSpec(int id) - { - Query.Where(x => x.Id == id) - .Include(x => x.Address); - } + public StoreByIdIncludeAddressSpec(int id) + { + Query.Where(x => x.Id == id) + .Include(x => x.Address); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdIncludeCompanyAndCountryAndStoresForCompanySpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdIncludeCompanyAndCountryAndStoresForCompanySpec.cs index 2722eb83..767e4279 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdIncludeCompanyAndCountryAndStoresForCompanySpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdIncludeCompanyAndCountryAndStoresForCompanySpec.cs @@ -2,10 +2,10 @@ public class StoreByIdIncludeCompanyAndCountryAndStoresForCompanySpec : Specification, ISingleResultSpecification { - public StoreByIdIncludeCompanyAndCountryAndStoresForCompanySpec(int id) - { - Query.Where(x => x.Id == id); - Query.Include(x => x.Company).ThenInclude(x => x!.Country); - Query.Include(x => x.Company).ThenInclude(x => x!.Stores).ThenInclude(x => x.Products); - } + public StoreByIdIncludeCompanyAndCountryAndStoresForCompanySpec(int id) + { + Query.Where(x => x.Id == id); + Query.Include(x => x.Company).ThenInclude(x => x!.Country); + Query.Include(x => x.Company).ThenInclude(x => x!.Stores).ThenInclude(x => x.Products); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdIncludeProductsSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdIncludeProductsSpec.cs index d366f739..ecfe7995 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdIncludeProductsSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdIncludeProductsSpec.cs @@ -2,9 +2,9 @@ public class StoreByIdIncludeProductsSpec : Specification, ISingleResultSpecification { - public StoreByIdIncludeProductsSpec(int id) - { - Query.Where(x => x.Id == id) - .Include(x => x.Products); - } + public StoreByIdIncludeProductsSpec(int id) + { + Query.Where(x => x.Id == id) + .Include(x => x.Products); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdIncludeProductsUsingStringSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdIncludeProductsUsingStringSpec.cs index 9fd5c7b3..befc9a81 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdIncludeProductsUsingStringSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdIncludeProductsUsingStringSpec.cs @@ -2,9 +2,9 @@ public class StoreByIdIncludeProductsUsingStringSpec : Specification, ISingleResultSpecification { - public StoreByIdIncludeProductsUsingStringSpec(int id) - { - Query.Where(x => x.Id == id) - .Include(nameof(Store.Products)); - } + public StoreByIdIncludeProductsUsingStringSpec(int id) + { + Query.Where(x => x.Id == id) + .Include(nameof(Store.Products)); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdSearchByNameAndCitySpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdSearchByNameAndCitySpec.cs index 8a71611e..b5875851 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdSearchByNameAndCitySpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdSearchByNameAndCitySpec.cs @@ -2,10 +2,10 @@ public class StoreByIdSearchByNameAndCitySpec : Specification { - public StoreByIdSearchByNameAndCitySpec(int id, string searchTerm) - { - Query.Where(x => x.Id == id) - .Search(x => x.Name!, "%" + searchTerm + "%", 1) - .Search(x => x.City!, "%" + searchTerm + "%", 2); - } + public StoreByIdSearchByNameAndCitySpec(int id, string searchTerm) + { + Query.Where(x => x.Id == id) + .Search(x => x.Name!, "%" + searchTerm + "%", 1) + .Search(x => x.City!, "%" + searchTerm + "%", 2); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdSearchByNameOrCitySpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdSearchByNameOrCitySpec.cs index a7c7fc9c..b9b50326 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdSearchByNameOrCitySpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdSearchByNameOrCitySpec.cs @@ -2,10 +2,10 @@ public class StoreByIdSearchByNameOrCitySpec : Specification { - public StoreByIdSearchByNameOrCitySpec(int id, string searchTerm) - { - Query.Where(x => x.Id == id) - .Search(x => x.Name!, "%" + searchTerm + "%") - .Search(x => x.City!, "%" + searchTerm + "%"); - } + public StoreByIdSearchByNameOrCitySpec(int id, string searchTerm) + { + Query.Where(x => x.Id == id) + .Search(x => x.Name!, "%" + searchTerm + "%") + .Search(x => x.City!, "%" + searchTerm + "%"); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdSpec.cs index d5e36842..4815d145 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreByIdSpec.cs @@ -2,8 +2,8 @@ public class StoreByIdSpec : Specification { - public StoreByIdSpec(int id) - { - Query.Where(x => x.Id == id); - } + public StoreByIdSpec(int id) + { + Query.Where(x => x.Id == id); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreDuplicateSkipSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreDuplicateSkipSpec.cs index 29cf9128..321a5658 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreDuplicateSkipSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreDuplicateSkipSpec.cs @@ -2,9 +2,9 @@ public class StoreDuplicateSkipSpec : Specification { - public StoreDuplicateSkipSpec() - { - Query.Skip(1) - .Skip(2); - } + public StoreDuplicateSkipSpec() + { + Query.Skip(1) + .Skip(2); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreDuplicateTakeSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreDuplicateTakeSpec.cs index f20d4082..2f2e755c 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreDuplicateTakeSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreDuplicateTakeSpec.cs @@ -2,9 +2,9 @@ public class StoreDuplicateTakeSpec : Specification { - public StoreDuplicateTakeSpec() - { - Query.Take(1) - .Take(2); - } + public StoreDuplicateTakeSpec() + { + Query.Take(1) + .Take(2); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreEmptySpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreEmptySpec.cs index e43fe15f..f6430750 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreEmptySpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreEmptySpec.cs @@ -2,8 +2,8 @@ public class StoreEmptySpec : Specification { - public StoreEmptySpec() - { + public StoreEmptySpec() + { - } + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreNamesEmptySpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreNamesEmptySpec.cs index 2887bdcd..54568e4e 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreNamesEmptySpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreNamesEmptySpec.cs @@ -2,8 +2,8 @@ public class StoreNamesEmptySpec : Specification { - public StoreNamesEmptySpec() - { + public StoreNamesEmptySpec() + { - } + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreNamesPaginatedSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreNamesPaginatedSpec.cs index 340ba6bb..cbccbb12 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreNamesPaginatedSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreNamesPaginatedSpec.cs @@ -2,12 +2,12 @@ public class StoreNamesPaginatedSpec : Specification { - public StoreNamesPaginatedSpec(int skip, int take) - { - Query.OrderBy(x => x.Id) - .Skip(skip) - .Take(take); + public StoreNamesPaginatedSpec(int skip, int take) + { + Query.OrderBy(x => x.Id) + .Skip(skip) + .Take(take); - Query.Select(x => x.Name); - } + Query.Select(x => x.Name); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreNamesSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreNamesSpec.cs index c4cc0cb4..df3972be 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreNamesSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreNamesSpec.cs @@ -2,8 +2,8 @@ public class StoreNamesSpec : Specification { - public StoreNamesSpec() - { - Query.Select(x => x.Name); - } + public StoreNamesSpec() + { + Query.Select(x => x.Name); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreNamesWithPostProcessingActionSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreNamesWithPostProcessingActionSpec.cs index a7295ef4..ec7e175b 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreNamesWithPostProcessingActionSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreNamesWithPostProcessingActionSpec.cs @@ -2,9 +2,9 @@ public class StoreNamesWithPostProcessingActionSpec : Specification { - public StoreNamesWithPostProcessingActionSpec() - { - Query.Select(x => x.Name) - .PostProcessingAction(x => x); - } + public StoreNamesWithPostProcessingActionSpec() + { + Query.Select(x => x.Name) + .PostProcessingAction(x => x); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreProductNamesEmptySpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreProductNamesEmptySpec.cs index 3312462c..95dad8be 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreProductNamesEmptySpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreProductNamesEmptySpec.cs @@ -2,8 +2,8 @@ public class StoreProductNamesEmptySpec : Specification { - public StoreProductNamesEmptySpec() - { + public StoreProductNamesEmptySpec() + { - } + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreProductNamesSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreProductNamesSpec.cs index 2a45e21c..9a342987 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreProductNamesSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreProductNamesSpec.cs @@ -2,8 +2,8 @@ public class StoreProductNamesSpec : Specification { - public StoreProductNamesSpec() - { - Query.SelectMany(s => s.Products.Select(p => p.Name)); - } + public StoreProductNamesSpec() + { + Query.SelectMany(s => s.Products.Select(p => p.Name)); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreSearchByNameAndCitySpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreSearchByNameAndCitySpec.cs index 0ac2e13f..2b52eb71 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreSearchByNameAndCitySpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreSearchByNameAndCitySpec.cs @@ -2,9 +2,9 @@ public class StoreSearchByNameAndCitySpec : Specification { - public StoreSearchByNameAndCitySpec(string searchTerm) - { - Query.Search(x => x.Name!, "%" + searchTerm + "%", 1) - .Search(x => x.City!, "%" + searchTerm + "%", 2); - } + public StoreSearchByNameAndCitySpec(string searchTerm) + { + Query.Search(x => x.Name!, "%" + searchTerm + "%", 1) + .Search(x => x.City!, "%" + searchTerm + "%", 2); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreSearchByNameOrCitySpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreSearchByNameOrCitySpec.cs index f442fcd7..e2d9d4d7 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreSearchByNameOrCitySpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreSearchByNameOrCitySpec.cs @@ -2,9 +2,9 @@ public class StoreSearchByNameOrCitySpec : Specification { - public StoreSearchByNameOrCitySpec(string searchTerm) - { - Query.Search(x => x.Name!, "%" + searchTerm + "%") - .Search(x => x.City!, "%" + searchTerm + "%"); - } + public StoreSearchByNameOrCitySpec(string searchTerm) + { + Query.Search(x => x.Name!, "%" + searchTerm + "%") + .Search(x => x.City!, "%" + searchTerm + "%"); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreSearchByNameSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreSearchByNameSpec.cs index 7f61ad28..8f5e69d2 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreSearchByNameSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreSearchByNameSpec.cs @@ -2,8 +2,8 @@ public class StoreSearchByNameSpec : Specification { - public StoreSearchByNameSpec(string searchTerm) - { - Query.Search(x => x.Name!, "%" + searchTerm + "%"); - } + public StoreSearchByNameSpec(string searchTerm) + { + Query.Search(x => x.Name!, "%" + searchTerm + "%"); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreWithPostProcessingActionSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreWithPostProcessingActionSpec.cs index e9cdfdd2..8649b60f 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreWithPostProcessingActionSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoreWithPostProcessingActionSpec.cs @@ -2,8 +2,8 @@ public class StoreWithPostProcessingActionSpec : Specification { - public StoreWithPostProcessingActionSpec() - { - Query.PostProcessingAction(x => x); - } + public StoreWithPostProcessingActionSpec() + { + Query.PostProcessingAction(x => x); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByCompanyOrderedDescByNameSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByCompanyOrderedDescByNameSpec.cs index 50c2852f..96def25b 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByCompanyOrderedDescByNameSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByCompanyOrderedDescByNameSpec.cs @@ -2,9 +2,9 @@ public class StoresByCompanyOrderedDescByNameSpec : Specification { - public StoresByCompanyOrderedDescByNameSpec(int companyId) - { - Query.Where(x => x.CompanyId == companyId) - .OrderByDescending(x => x.Name); - } + public StoresByCompanyOrderedDescByNameSpec(int companyId) + { + Query.Where(x => x.CompanyId == companyId) + .OrderByDescending(x => x.Name); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByCompanyOrderedDescByNameThenByDescIdSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByCompanyOrderedDescByNameThenByDescIdSpec.cs index 1caef272..6839be4d 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByCompanyOrderedDescByNameThenByDescIdSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByCompanyOrderedDescByNameThenByDescIdSpec.cs @@ -2,10 +2,10 @@ public class StoresByCompanyOrderedDescByNameThenByDescIdSpec : Specification { - public StoresByCompanyOrderedDescByNameThenByDescIdSpec(int companyId) - { - Query.Where(x => x.CompanyId == companyId) - .OrderByDescending(x => x.Name) - .ThenByDescending(x => x.Id); - } + public StoresByCompanyOrderedDescByNameThenByDescIdSpec(int companyId) + { + Query.Where(x => x.CompanyId == companyId) + .OrderByDescending(x => x.Name) + .ThenByDescending(x => x.Id); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByCompanyOrderedDescByNameThenByIdSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByCompanyOrderedDescByNameThenByIdSpec.cs index c14fcbcc..d80d5ee7 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByCompanyOrderedDescByNameThenByIdSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByCompanyOrderedDescByNameThenByIdSpec.cs @@ -2,10 +2,10 @@ public class StoresByCompanyOrderedDescByNameThenByIdSpec : Specification { - public StoresByCompanyOrderedDescByNameThenByIdSpec(int companyId) - { - Query.Where(x => x.CompanyId == companyId) - .OrderByDescending(x => x.Name) - .ThenBy(x => x.Id); - } + public StoresByCompanyOrderedDescByNameThenByIdSpec(int companyId) + { + Query.Where(x => x.CompanyId == companyId) + .OrderByDescending(x => x.Name) + .ThenBy(x => x.Id); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByCompanyPaginatedOrderedDescByNameSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByCompanyPaginatedOrderedDescByNameSpec.cs index 12dc0ecb..844aa480 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByCompanyPaginatedOrderedDescByNameSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByCompanyPaginatedOrderedDescByNameSpec.cs @@ -2,11 +2,11 @@ public class StoresByCompanyPaginatedOrderedDescByNameSpec : Specification { - public StoresByCompanyPaginatedOrderedDescByNameSpec(int companyId, int skip, int take) - { - Query.Where(x => x.CompanyId == companyId) - .Skip(skip) - .Take(take) - .OrderByDescending(x => x.Name); - } + public StoresByCompanyPaginatedOrderedDescByNameSpec(int companyId, int skip, int take) + { + Query.Where(x => x.CompanyId == companyId) + .Skip(skip) + .Take(take) + .OrderByDescending(x => x.Name); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByCompanyPaginatedSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByCompanyPaginatedSpec.cs index b4f77ada..1fca13cf 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByCompanyPaginatedSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByCompanyPaginatedSpec.cs @@ -2,11 +2,11 @@ public class StoresByCompanyPaginatedSpec : Specification { - public StoresByCompanyPaginatedSpec(int companyId, int skip, int take) - { - Query.Where(x => x.CompanyId == companyId) - .OrderBy(x => x.CompanyId) - .Skip(skip) - .Take(take); - } + public StoresByCompanyPaginatedSpec(int companyId, int skip, int take) + { + Query.Where(x => x.CompanyId == companyId) + .OrderBy(x => x.CompanyId) + .Skip(skip) + .Take(take); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByIdListSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByIdListSpec.cs index 1ee40d44..d7a0432c 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByIdListSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresByIdListSpec.cs @@ -5,8 +5,8 @@ namespace Ardalis.Specification.UnitTests.Fixture.Specs; public class StoresByIdListSpec : Specification { - public StoresByIdListSpec(IEnumerable ids) - { - Query.Where(x => ids.Contains(x.Id)); - } + public StoresByIdListSpec(IEnumerable ids) + { + Query.Where(x => ids.Contains(x.Id)); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresOrderedDescendingByNameSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresOrderedDescendingByNameSpec.cs index 0f754495..4c458706 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresOrderedDescendingByNameSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresOrderedDescendingByNameSpec.cs @@ -2,8 +2,8 @@ public class StoresOrderedDescendingByNameSpec : Specification { - public StoresOrderedDescendingByNameSpec() - { - Query.OrderByDescending(x => x.Name); - } + public StoresOrderedDescendingByNameSpec() + { + Query.OrderByDescending(x => x.Name); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresOrderedSpecByName.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresOrderedSpecByName.cs index d45f7665..f8822376 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresOrderedSpecByName.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresOrderedSpecByName.cs @@ -2,8 +2,8 @@ public class StoresOrderedSpecByName : Specification { - public StoresOrderedSpecByName() - { - Query.OrderBy(x => x.Name); - } + public StoresOrderedSpecByName() + { + Query.OrderBy(x => x.Name); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresOrderedTwoChainsSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresOrderedTwoChainsSpec.cs index 4aa1fd9f..49eefd34 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresOrderedTwoChainsSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresOrderedTwoChainsSpec.cs @@ -2,9 +2,9 @@ public class StoresOrderedTwoChainsSpec : Specification { - public StoresOrderedTwoChainsSpec() - { - Query.OrderBy(x => x.Name) - .OrderBy(x => x.Id); - } + public StoresOrderedTwoChainsSpec() + { + Query.OrderBy(x => x.Name) + .OrderBy(x => x.Id); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresPaginatedSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresPaginatedSpec.cs index 21b7db63..57432b23 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresPaginatedSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/Specs/StoresPaginatedSpec.cs @@ -2,10 +2,10 @@ public class StoresPaginatedSpec : Specification { - public StoresPaginatedSpec(int skip, int take) - { - Query.OrderBy(s => s.Id) - .Skip(skip) - .Take(take); - } + public StoresPaginatedSpec(int skip, int take) + { + Query.OrderBy(s => s.Id) + .Skip(skip) + .Take(take); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/CompanyIncludeFilteredStoresSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/CompanyIncludeFilteredStoresSpec.cs index 43ae00c6..e39dd17b 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/CompanyIncludeFilteredStoresSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/CompanyIncludeFilteredStoresSpec.cs @@ -2,9 +2,9 @@ public class CompanyIncludeFilteredStoresSpec : Specification { - public CompanyIncludeFilteredStoresSpec(int id) - { - Query.Where(x => x.Id == id) - .Include(x => x.Stores.Where(s => s.Id == 1)); - } + public CompanyIncludeFilteredStoresSpec(int id) + { + Query.Where(x => x.Id == id) + .Include(x => x.Stores.Where(s => s.Id == 1)); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeAddressAndProductsSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeAddressAndProductsSpec.cs index 9352d180..54ab0aec 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeAddressAndProductsSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeAddressAndProductsSpec.cs @@ -2,9 +2,9 @@ public class StoreIncludeAddressAndProductsSpec : Specification { - public StoreIncludeAddressAndProductsSpec() - { - Query.Include(x => x.Products) - .Include(x => x!.Address); - } + public StoreIncludeAddressAndProductsSpec() + { + Query.Include(x => x.Products) + .Include(x => x!.Address); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeAddressSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeAddressSpec.cs index 9c37e1fb..7f38dcd8 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeAddressSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeAddressSpec.cs @@ -2,8 +2,8 @@ public class StoreIncludeAddressSpec : Specification { - public StoreIncludeAddressSpec() - { - Query.Include(x => x.Address); - } + public StoreIncludeAddressSpec() + { + Query.Include(x => x.Address); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeCompanyCountryDotSeparatedSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeCompanyCountryDotSeparatedSpec.cs index 91ff257a..61e3d00c 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeCompanyCountryDotSeparatedSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeCompanyCountryDotSeparatedSpec.cs @@ -2,8 +2,8 @@ public class StoreIncludeCompanyCountryDotSeparatedSpec : Specification { - public StoreIncludeCompanyCountryDotSeparatedSpec() - { - Query.Include(x => x.Company!.Country); - } + public StoreIncludeCompanyCountryDotSeparatedSpec() + { + Query.Include(x => x.Company!.Country); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeCompanyThenCountryAsStringSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeCompanyThenCountryAsStringSpec.cs index 4d76c1a3..788630a3 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeCompanyThenCountryAsStringSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeCompanyThenCountryAsStringSpec.cs @@ -2,8 +2,8 @@ public class StoreIncludeCompanyThenCountryAsStringSpec : Specification { - public StoreIncludeCompanyThenCountryAsStringSpec() - { - Query.Include($"{nameof(Company)}.{nameof(Company.Country)}"); - } + public StoreIncludeCompanyThenCountryAsStringSpec() + { + Query.Include($"{nameof(Company)}.{nameof(Company.Country)}"); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeCompanyThenCountrySpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeCompanyThenCountrySpec.cs index 7f8f0c11..2dec8e07 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeCompanyThenCountrySpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeCompanyThenCountrySpec.cs @@ -2,9 +2,9 @@ public class StoreIncludeCompanyThenCountrySpec : Specification { - public StoreIncludeCompanyThenCountrySpec() - { - Query.Include(x => x.Company) - .ThenInclude(x => x!.Country); - } + public StoreIncludeCompanyThenCountrySpec() + { + Query.Include(x => x.Company) + .ThenInclude(x => x!.Country); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeCompanyThenNameSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeCompanyThenNameSpec.cs index 20348593..1787a365 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeCompanyThenNameSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeCompanyThenNameSpec.cs @@ -2,9 +2,9 @@ public class StoreIncludeCompanyThenNameSpec : Specification { - public StoreIncludeCompanyThenNameSpec() - { - Query.Include(x => x.Company) - .ThenInclude(x => x!.Name); - } + public StoreIncludeCompanyThenNameSpec() + { + Query.Include(x => x.Company) + .ThenInclude(x => x!.Name); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeCompanyThenStoresSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeCompanyThenStoresSpec.cs index 1413021b..3488b0f7 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeCompanyThenStoresSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeCompanyThenStoresSpec.cs @@ -2,10 +2,10 @@ public class StoreIncludeCompanyThenStoresSpec : Specification { - public StoreIncludeCompanyThenStoresSpec() - { - Query.Include(x => x.Company) - .ThenInclude(x => x!.Stores) - .ThenInclude(x => x.Products); - } + public StoreIncludeCompanyThenStoresSpec() + { + Query.Include(x => x.Company) + .ThenInclude(x => x!.Stores) + .ThenInclude(x => x.Products); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeMethodOfNavigationSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeMethodOfNavigationSpec.cs index e4b1bba6..67dce23c 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeMethodOfNavigationSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeMethodOfNavigationSpec.cs @@ -2,8 +2,8 @@ public class StoreIncludeMethodOfNavigationSpec : Specification { - public StoreIncludeMethodOfNavigationSpec() - { - Query.Include(x => x.Address!.GetSomethingFromAddress()); - } + public StoreIncludeMethodOfNavigationSpec() + { + Query.Include(x => x.Address!.GetSomethingFromAddress()); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeMethodSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeMethodSpec.cs index f9cce94a..817270af 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeMethodSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeMethodSpec.cs @@ -2,8 +2,8 @@ public class StoreIncludeMethodSpec : Specification { - public StoreIncludeMethodSpec() - { - Query.Include(x => Store.GetSomethingFromStore()); - } + public StoreIncludeMethodSpec() + { + Query.Include(x => Store.GetSomethingFromStore()); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeNameSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeNameSpec.cs index d52f326d..60dfaf7a 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeNameSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeNameSpec.cs @@ -2,8 +2,8 @@ public class StoreIncludeNameSpec : Specification { - public StoreIncludeNameSpec() - { - Query.Include(x => x.Name); - } + public StoreIncludeNameSpec() + { + Query.Include(x => x.Name); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeProductsSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeProductsSpec.cs index 3fd09d25..841c889c 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeProductsSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreIncludeProductsSpec.cs @@ -2,8 +2,8 @@ public class StoreIncludeProductsSpec : Specification { - public StoreIncludeProductsSpec() - { - Query.Include(x => x.Products); - } + public StoreIncludeProductsSpec() + { + Query.Include(x => x.Products); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreWithFaultyIncludeSpec.cs b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreWithFaultyIncludeSpec.cs index 1bd37bf3..51e092d1 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreWithFaultyIncludeSpec.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/Fixture/SpecsForIncludeTests/StoreWithFaultyIncludeSpec.cs @@ -2,8 +2,8 @@ public class StoreWithFaultyIncludeSpec : Specification { - public StoreWithFaultyIncludeSpec() - { - Query.Include(x => x.Id == 1 && x.Name == "Something"); - } + public StoreWithFaultyIncludeSpec() + { + Query.Include(x => x.Id == 1 && x.Name == "Something"); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/IncludeExpressionInfoTests.cs b/Specification/tests/Ardalis.Specification.UnitTests/IncludeExpressionInfoTests.cs index 184145a3..b45ef907 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/IncludeExpressionInfoTests.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/IncludeExpressionInfoTests.cs @@ -5,46 +5,46 @@ namespace Ardalis.Specification.UnitTests; public class IncludeExpressionInfoTests { - private readonly Expression> _expr; - - public IncludeExpressionInfoTests() - { - _expr = x => x.Country!; - } - - [Fact] - public void ThrowsArgumentNullException_GivenNullForLambdaExpression() - { - Action sutAction = () => new IncludeExpressionInfo(null!, typeof(Company), typeof(Country)); - - sutAction.Should() - .Throw(); - } - - [Fact] - public void ThrowsArgumentNullException_GivenNullForEntityType() - { - Action sutAction = () => new IncludeExpressionInfo(_expr, null!, typeof(Country)); - - sutAction.Should() - .Throw(); - } - - [Fact] - public void ThrowsArgumentNullException_GivenNullForPropertyType() - { - Action sutAction = () => new IncludeExpressionInfo(_expr, typeof(Company), null!); - - sutAction.Should() - .Throw(); - } - - [Fact] - public void ThrowsArgumentNullException_GivenNullForPreviousPropertyType() - { - Action sutAction = () => new IncludeExpressionInfo(_expr, typeof(Company), typeof(Country), null!); - - sutAction.Should() - .Throw(); - } + private readonly Expression> _expr; + + public IncludeExpressionInfoTests() + { + _expr = x => x.Country!; + } + + [Fact] + public void ThrowsArgumentNullException_GivenNullForLambdaExpression() + { + Action sutAction = () => new IncludeExpressionInfo(null!, typeof(Company), typeof(Country)); + + sutAction.Should() + .Throw(); + } + + [Fact] + public void ThrowsArgumentNullException_GivenNullForEntityType() + { + Action sutAction = () => new IncludeExpressionInfo(_expr, null!, typeof(Country)); + + sutAction.Should() + .Throw(); + } + + [Fact] + public void ThrowsArgumentNullException_GivenNullForPropertyType() + { + Action sutAction = () => new IncludeExpressionInfo(_expr, typeof(Company), null!); + + sutAction.Should() + .Throw(); + } + + [Fact] + public void ThrowsArgumentNullException_GivenNullForPreviousPropertyType() + { + Action sutAction = () => new IncludeExpressionInfo(_expr, typeof(Company), typeof(Country), null!); + + sutAction.Should() + .Throw(); + } } diff --git a/Specification/tests/Ardalis.Specification.UnitTests/ValidatorTests/SpecificationValidator_Tests.cs b/Specification/tests/Ardalis.Specification.UnitTests/ValidatorTests/SpecificationValidator_Tests.cs index cfe92db1..4f6baadd 100644 --- a/Specification/tests/Ardalis.Specification.UnitTests/ValidatorTests/SpecificationValidator_Tests.cs +++ b/Specification/tests/Ardalis.Specification.UnitTests/ValidatorTests/SpecificationValidator_Tests.cs @@ -4,86 +4,86 @@ namespace Ardalis.Specification.UnitTests.ValidatorTests; public class SpecificationValidator_Tests { - private readonly Store _store = StoreSeed.Get().Single(x => x.Id == StoreSeed.VALID_Search_ID); + private readonly Store _store = StoreSeed.Get().Single(x => x.Id == StoreSeed.VALID_Search_ID); - public void ReturnsTrue_GivenStoreByIdSearchByNameAndCitySpec_WithValidValues() - { - var spec = new StoreByIdSearchByNameAndCitySpec(StoreSeed.VALID_Search_ID, StoreSeed.VALID_Search_City_Name_Key); + public void ReturnsTrue_GivenStoreByIdSearchByNameAndCitySpec_WithValidValues() + { + var spec = new StoreByIdSearchByNameAndCitySpec(StoreSeed.VALID_Search_ID, StoreSeed.VALID_Search_City_Name_Key); - var result = spec.IsSatisfiedBy(_store); + var result = spec.IsSatisfiedBy(_store); - result.Should().BeTrue(); - } + result.Should().BeTrue(); + } - public void ReturnsFalse_GivenStoreByIdSearchByNameAndCitySpec_WithInvalidId() - { - var spec = new StoreByIdSearchByNameAndCitySpec(1, StoreSeed.VALID_Search_City_Name_Key); + public void ReturnsFalse_GivenStoreByIdSearchByNameAndCitySpec_WithInvalidId() + { + var spec = new StoreByIdSearchByNameAndCitySpec(1, StoreSeed.VALID_Search_City_Name_Key); - var result = spec.IsSatisfiedBy(_store); + var result = spec.IsSatisfiedBy(_store); - result.Should().BeFalse(); - } + result.Should().BeFalse(); + } - public void ReturnsFalse_GivenStoreByIdSearchByNameAndCitySpec_WithInvalidNameSearchString() - { - var spec = new StoreByIdSearchByNameAndCitySpec(StoreSeed.VALID_Search_ID, StoreSeed.VALID_Search_City_Key); + public void ReturnsFalse_GivenStoreByIdSearchByNameAndCitySpec_WithInvalidNameSearchString() + { + var spec = new StoreByIdSearchByNameAndCitySpec(StoreSeed.VALID_Search_ID, StoreSeed.VALID_Search_City_Key); - var result = spec.IsSatisfiedBy(_store); + var result = spec.IsSatisfiedBy(_store); - result.Should().BeFalse(); - } + result.Should().BeFalse(); + } - public void ReturnsFalse_GivenStoreByIdSearchByNameAndCitySpec_WithInvalidCitySearchString() - { - var spec = new StoreByIdSearchByNameAndCitySpec(StoreSeed.VALID_Search_ID, StoreSeed.VALID_Search_Name_Key); + public void ReturnsFalse_GivenStoreByIdSearchByNameAndCitySpec_WithInvalidCitySearchString() + { + var spec = new StoreByIdSearchByNameAndCitySpec(StoreSeed.VALID_Search_ID, StoreSeed.VALID_Search_Name_Key); - var result = spec.IsSatisfiedBy(_store); + var result = spec.IsSatisfiedBy(_store); - result.Should().BeFalse(); - } + result.Should().BeFalse(); + } - public void ReturnsFalse_StoreByIdSearchByNameAndCitySpecSpec_WithInvalidCityAndNameSearchString() - { - var spec = new StoreByIdSearchByNameAndCitySpec(StoreSeed.VALID_Search_ID, "random"); + public void ReturnsFalse_StoreByIdSearchByNameAndCitySpecSpec_WithInvalidCityAndNameSearchString() + { + var spec = new StoreByIdSearchByNameAndCitySpec(StoreSeed.VALID_Search_ID, "random"); - var result = spec.IsSatisfiedBy(_store); + var result = spec.IsSatisfiedBy(_store); - result.Should().BeFalse(); - } + result.Should().BeFalse(); + } - public void ReturnsTrue_StoreByIdSearchByNameOrCitySpecSpec_WithValidValues() - { - var spec = new StoreByIdSearchByNameOrCitySpec(StoreSeed.VALID_Search_ID, StoreSeed.VALID_Search_City_Name_Key); + public void ReturnsTrue_StoreByIdSearchByNameOrCitySpecSpec_WithValidValues() + { + var spec = new StoreByIdSearchByNameOrCitySpec(StoreSeed.VALID_Search_ID, StoreSeed.VALID_Search_City_Name_Key); - var result = spec.IsSatisfiedBy(_store); + var result = spec.IsSatisfiedBy(_store); - result.Should().BeTrue(); - } + result.Should().BeTrue(); + } - public void ReturnsTrue_StoreByIdSearchByNameOrCitySpecSpec_WithInvalidNameSearchString() - { - var spec = new StoreByIdSearchByNameOrCitySpec(StoreSeed.VALID_Search_ID, StoreSeed.VALID_Search_City_Key); + public void ReturnsTrue_StoreByIdSearchByNameOrCitySpecSpec_WithInvalidNameSearchString() + { + var spec = new StoreByIdSearchByNameOrCitySpec(StoreSeed.VALID_Search_ID, StoreSeed.VALID_Search_City_Key); - var result = spec.IsSatisfiedBy(_store); + var result = spec.IsSatisfiedBy(_store); - result.Should().BeTrue(); - } + result.Should().BeTrue(); + } - public void ReturnsTrue_StoreByIdSearchByNameOrCitySpecSpec_WithInvalidCitySearchString() - { - var spec = new StoreByIdSearchByNameOrCitySpec(StoreSeed.VALID_Search_ID, StoreSeed.VALID_Search_Name_Key); + public void ReturnsTrue_StoreByIdSearchByNameOrCitySpecSpec_WithInvalidCitySearchString() + { + var spec = new StoreByIdSearchByNameOrCitySpec(StoreSeed.VALID_Search_ID, StoreSeed.VALID_Search_Name_Key); - var result = spec.IsSatisfiedBy(_store); + var result = spec.IsSatisfiedBy(_store); - result.Should().BeTrue(); - } + result.Should().BeTrue(); + } - public void ReturnsFalse_StoreByIdSearchByNameOrCitySpecSpec_WithInvalidCityAndNameSearchString() - { - var spec = new StoreByIdSearchByNameOrCitySpec(StoreSeed.VALID_Search_ID, "random"); + public void ReturnsFalse_StoreByIdSearchByNameOrCitySpecSpec_WithInvalidCityAndNameSearchString() + { + var spec = new StoreByIdSearchByNameOrCitySpec(StoreSeed.VALID_Search_ID, "random"); - var result = spec.IsSatisfiedBy(_store); + var result = spec.IsSatisfiedBy(_store); - result.Should().BeFalse(); - } + result.Should().BeFalse(); + } } diff --git a/sample/Ardalis.SampleApp.Core/Entities/CustomerAggregate/Customer.cs b/sample/Ardalis.SampleApp.Core/Entities/CustomerAggregate/Customer.cs index a9ed1faf..82f2ef97 100644 --- a/sample/Ardalis.SampleApp.Core/Entities/CustomerAggregate/Customer.cs +++ b/sample/Ardalis.SampleApp.Core/Entities/CustomerAggregate/Customer.cs @@ -7,48 +7,48 @@ namespace Ardalis.SampleApp.Core.Entities.CustomerAggregate; public class Customer : IAggregateRoot { - public int Id { get; private set; } - public string Name { get; private set; } - public string Email { get; private set; } - public string Address { get; private set; } + public int Id { get; private set; } + public string Name { get; private set; } + public string Email { get; private set; } + public string Address { get; private set; } - public IEnumerable Stores => _stores.AsEnumerable(); - private readonly List _stores = new(); + public IEnumerable Stores => _stores.AsEnumerable(); + private readonly List _stores = new(); - public Customer(string name, string email, string address) - { - Guard.Against.NullOrEmpty(name, nameof(name)); - Guard.Against.NullOrEmpty(email, nameof(email)); + public Customer(string name, string email, string address) + { + Guard.Against.NullOrEmpty(name, nameof(name)); + Guard.Against.NullOrEmpty(email, nameof(email)); - Name = name; - Email = email; - Address = address; - } + Name = name; + Email = email; + Address = address; + } - public Store GetStore(int storeId) - { - var store = Stores.FirstOrDefault(x => x.Id == storeId); + public Store GetStore(int storeId) + { + var store = Stores.FirstOrDefault(x => x.Id == storeId); - Guard.Against.Null(store, nameof(store)); + Guard.Against.Null(store, nameof(store)); - return store; - } + return store; + } - public Store AddStore(Store store) - { - Guard.Against.Null(store, nameof(store)); + public Store AddStore(Store store) + { + Guard.Against.Null(store, nameof(store)); - // Do some other operation while adding it. + // Do some other operation while adding it. - _stores.Add(store); + _stores.Add(store); - return store; - } + return store; + } - public void DeleteStore(int storeID) - { - var store = GetStore(storeID); + public void DeleteStore(int storeID) + { + var store = GetStore(storeID); - _stores.Remove(store); - } + _stores.Remove(store); + } } diff --git a/sample/Ardalis.SampleApp.Core/Entities/CustomerAggregate/Store.cs b/sample/Ardalis.SampleApp.Core/Entities/CustomerAggregate/Store.cs index ccbd4301..d23ce684 100644 --- a/sample/Ardalis.SampleApp.Core/Entities/CustomerAggregate/Store.cs +++ b/sample/Ardalis.SampleApp.Core/Entities/CustomerAggregate/Store.cs @@ -4,17 +4,17 @@ namespace Ardalis.SampleApp.Core.Entities.CustomerAggregate; public class Store { - public int Id { get; private set; } - public string Name { get; private set; } - public string Address { get; private set; } + public int Id { get; private set; } + public string Name { get; private set; } + public string Address { get; private set; } - public int CustomerId { get; private set; } + public int CustomerId { get; private set; } - public Store(string name, string address) - { - Guard.Against.NullOrEmpty(name, nameof(name)); + public Store(string name, string address) + { + Guard.Against.NullOrEmpty(name, nameof(name)); - this.Name = name; - this.Address = address; - } + this.Name = name; + this.Address = address; + } } diff --git a/sample/Ardalis.SampleApp.Core/Entities/Seeds/CustomerSeed.cs b/sample/Ardalis.SampleApp.Core/Entities/Seeds/CustomerSeed.cs index 543ff001..52186909 100644 --- a/sample/Ardalis.SampleApp.Core/Entities/Seeds/CustomerSeed.cs +++ b/sample/Ardalis.SampleApp.Core/Entities/Seeds/CustomerSeed.cs @@ -5,19 +5,19 @@ namespace Ardalis.SampleApp.Core.Entities.Seeds; public static class CustomerSeed { - public static List Seed() - { - List output = new List(); - - for (int i = 1; i <= 100000; i++) + public static List Seed() { - var customer = new Customer($"Customer{i}", $"Email{i}@local", $"Customer{i} address"); - customer.AddStore(new Store($"Store{i}-1", $"Store{i}-1 address")); - customer.AddStore(new Store($"Store{i}-2", $"Store{i}-2 address")); + List output = new List(); - output.Add(customer); - } + for (int i = 1; i <= 100000; i++) + { + var customer = new Customer($"Customer{i}", $"Email{i}@local", $"Customer{i} address"); + customer.AddStore(new Store($"Store{i}-1", $"Store{i}-1 address")); + customer.AddStore(new Store($"Store{i}-2", $"Store{i}-2 address")); - return output; - } + output.Add(customer); + } + + return output; + } } diff --git a/sample/Ardalis.SampleApp.Core/Interfaces/ICustomerRepository.cs b/sample/Ardalis.SampleApp.Core/Interfaces/ICustomerRepository.cs index b2c947a9..41f00172 100644 --- a/sample/Ardalis.SampleApp.Core/Interfaces/ICustomerRepository.cs +++ b/sample/Ardalis.SampleApp.Core/Interfaces/ICustomerRepository.cs @@ -6,6 +6,6 @@ namespace Ardalis.SampleApp.Core.Interfaces; public interface ICustomerRepository { - // This is just to demonstrate that at anytime you can create custom repositories, and use to create some complex queries working directly with EF or your ORM. - Task> GetCustomers(string addressSearchTerm); + // This is just to demonstrate that at anytime you can create custom repositories, and use to create some complex queries working directly with EF or your ORM. + Task> GetCustomers(string addressSearchTerm); } diff --git a/sample/Ardalis.SampleApp.Core/Specifications/CustomerByNameSpec.cs b/sample/Ardalis.SampleApp.Core/Specifications/CustomerByNameSpec.cs index a03b5a57..f91178ae 100644 --- a/sample/Ardalis.SampleApp.Core/Specifications/CustomerByNameSpec.cs +++ b/sample/Ardalis.SampleApp.Core/Specifications/CustomerByNameSpec.cs @@ -8,10 +8,10 @@ namespace Ardalis.SampleApp.Core.Specifications; /// public class CustomerByNameSpec : SingleResultSpecification { - public CustomerByNameSpec(string name) - { - Query.Where(x => x.Name == name) - .OrderBy(x => x.Name) - .ThenByDescending(x => x.Address); - } + public CustomerByNameSpec(string name) + { + Query.Where(x => x.Name == name) + .OrderBy(x => x.Name) + .ThenByDescending(x => x.Address); + } } diff --git a/sample/Ardalis.SampleApp.Core/Specifications/CustomerByNameWithStoresSpec.cs b/sample/Ardalis.SampleApp.Core/Specifications/CustomerByNameWithStoresSpec.cs index d90de7de..a6e6f80f 100644 --- a/sample/Ardalis.SampleApp.Core/Specifications/CustomerByNameWithStoresSpec.cs +++ b/sample/Ardalis.SampleApp.Core/Specifications/CustomerByNameWithStoresSpec.cs @@ -8,10 +8,10 @@ namespace Ardalis.SampleApp.Core.Specifications; /// public class CustomerByNameWithStoresSpec : SingleResultSpecification { - public CustomerByNameWithStoresSpec(string name) - { - Query.Where(x => x.Name == name) - .Include(x => x.Stores) - .EnableCache(nameof(CustomerByNameWithStoresSpec), name); - } + public CustomerByNameWithStoresSpec(string name) + { + Query.Where(x => x.Name == name) + .Include(x => x.Stores) + .EnableCache(nameof(CustomerByNameWithStoresSpec), name); + } } diff --git a/sample/Ardalis.SampleApp.Core/Specifications/CustomerSpec.cs b/sample/Ardalis.SampleApp.Core/Specifications/CustomerSpec.cs index 0bb3420d..97964b1a 100644 --- a/sample/Ardalis.SampleApp.Core/Specifications/CustomerSpec.cs +++ b/sample/Ardalis.SampleApp.Core/Specifications/CustomerSpec.cs @@ -9,25 +9,25 @@ namespace Ardalis.SampleApp.Core.Specifications; /// public class CustomerSpec : Specification { - public CustomerSpec(CustomerFilter filter) - { - Query.OrderBy(x => x.Name) - .ThenByDescending(x => x.Address); + public CustomerSpec(CustomerFilter filter) + { + Query.OrderBy(x => x.Name) + .ThenByDescending(x => x.Address); - if (filter.LoadChildren) - Query.Include(x => x.Stores); + if (filter.LoadChildren) + Query.Include(x => x.Stores); - if (filter.IsPagingEnabled) - Query.Skip(PaginationHelper.CalculateSkip(filter)) - .Take(PaginationHelper.CalculateTake(filter)); + if (filter.IsPagingEnabled) + Query.Skip(PaginationHelper.CalculateSkip(filter)) + .Take(PaginationHelper.CalculateTake(filter)); - if (!string.IsNullOrEmpty(filter.Name)) - Query.Where(x => x.Name == filter.Name); + 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.Email)) + Query.Where(x => x.Email == filter.Email); - if (!string.IsNullOrEmpty(filter.Address)) - Query.Search(x => x.Address, "%" + filter.Address + "%"); - } + if (!string.IsNullOrEmpty(filter.Address)) + Query.Search(x => x.Address, "%" + filter.Address + "%"); + } } diff --git a/sample/Ardalis.SampleApp.Core/Specifications/Filters/BaseFilter.cs b/sample/Ardalis.SampleApp.Core/Specifications/Filters/BaseFilter.cs index 3f46e75f..c767a762 100644 --- a/sample/Ardalis.SampleApp.Core/Specifications/Filters/BaseFilter.cs +++ b/sample/Ardalis.SampleApp.Core/Specifications/Filters/BaseFilter.cs @@ -2,9 +2,9 @@ public class BaseFilter { - public bool LoadChildren { get; set; } - public bool IsPagingEnabled { get; set; } + public bool LoadChildren { get; set; } + public bool IsPagingEnabled { get; set; } - public int Page { get; set; } - public int PageSize { get; set; } + public int Page { get; set; } + public int PageSize { get; set; } } diff --git a/sample/Ardalis.SampleApp.Core/Specifications/Filters/CustomerFilter.cs b/sample/Ardalis.SampleApp.Core/Specifications/Filters/CustomerFilter.cs index 458f85ee..ae5b0d03 100644 --- a/sample/Ardalis.SampleApp.Core/Specifications/Filters/CustomerFilter.cs +++ b/sample/Ardalis.SampleApp.Core/Specifications/Filters/CustomerFilter.cs @@ -2,7 +2,7 @@ public class CustomerFilter : BaseFilter { - public string Name { get; set; } - public string Email { get; set; } - public string Address { get; set; } + public string Name { get; set; } + public string Email { get; set; } + public string Address { get; set; } } diff --git a/sample/Ardalis.SampleApp.Core/Specifications/PaginationHelper.cs b/sample/Ardalis.SampleApp.Core/Specifications/PaginationHelper.cs index ba7ad829..a8b81b92 100644 --- a/sample/Ardalis.SampleApp.Core/Specifications/PaginationHelper.cs +++ b/sample/Ardalis.SampleApp.Core/Specifications/PaginationHelper.cs @@ -4,26 +4,26 @@ namespace Ardalis.SampleApp.Core.Specifications; public static class PaginationHelper { - public static int DefaultPage => 1; - public static int DefaultPageSize => 10; + public static int DefaultPage => 1; + public static int DefaultPageSize => 10; - public static int CalculateTake(int pageSize) - { - return pageSize <= 0 ? DefaultPageSize : pageSize; - } - public static int CalculateSkip(int pageSize, int page) - { - page = page <= 0 ? DefaultPage : page; + public static int CalculateTake(int pageSize) + { + return pageSize <= 0 ? DefaultPageSize : pageSize; + } + public static int CalculateSkip(int pageSize, int page) + { + page = page <= 0 ? DefaultPage : page; - return CalculateTake(pageSize) * (page - 1); - } + return CalculateTake(pageSize) * (page - 1); + } - public static int CalculateTake(BaseFilter baseFilter) - { - return CalculateTake(baseFilter.PageSize); - } - public static int CalculateSkip(BaseFilter baseFilter) - { - return CalculateSkip(baseFilter.PageSize, baseFilter.Page); - } + public static int CalculateTake(BaseFilter baseFilter) + { + return CalculateTake(baseFilter.PageSize); + } + public static int CalculateSkip(BaseFilter baseFilter) + { + return CalculateSkip(baseFilter.PageSize, baseFilter.Page); + } } diff --git a/sample/Ardalis.SampleApp.Infrastructure/Data/CachedCustomerRepository.cs b/sample/Ardalis.SampleApp.Infrastructure/Data/CachedCustomerRepository.cs index 49ecf3c0..2d2339a2 100644 --- a/sample/Ardalis.SampleApp.Infrastructure/Data/CachedCustomerRepository.cs +++ b/sample/Ardalis.SampleApp.Infrastructure/Data/CachedCustomerRepository.cs @@ -12,147 +12,147 @@ namespace Ardalis.SampleApp.Infrastructure.Data; /// public class CachedRepository : IReadRepository where T : class, IAggregateRoot { - private readonly IMemoryCache _cache; - private readonly ILogger> _logger; - private readonly MyRepository _sourceRepository; - private readonly MemoryCacheEntryOptions _cacheOptions; - - public CachedRepository(IMemoryCache cache, - ILogger> logger, - MyRepository sourceRepository) - { - _cache = cache; - _logger = logger; - _sourceRepository = sourceRepository; - - _cacheOptions = new MemoryCacheEntryOptions() - .SetAbsoluteExpiration(relative: TimeSpan.FromSeconds(10)); - } - - /// - public virtual IAsyncEnumerable AsAsyncEnumerable(ISpecification specification) - { - return _sourceRepository.AsAsyncEnumerable(specification); - } - - /// - public Task AnyAsync(Specification.ISpecification specification, CancellationToken cancellationToken = default) - { - // TODO: Add Caching - return _sourceRepository.AnyAsync(specification, cancellationToken); - } - - /// - public Task AnyAsync(CancellationToken cancellationToken = default) - { - // TODO: Add Caching - return _sourceRepository.AnyAsync(cancellationToken); - } - - /// - public Task CountAsync(Specification.ISpecification specification, CancellationToken cancellationToken = default) - { - // TODO: Add Caching - return _sourceRepository.CountAsync(specification, cancellationToken); - } - - /// - public Task CountAsync(CancellationToken cancellationToken = default) - { - // TODO: Add Caching - return _sourceRepository.CountAsync(cancellationToken); - } - - /// - public Task GetByIdAsync(int id, CancellationToken cancellationToken = default) - { - return _sourceRepository.GetByIdAsync(id, cancellationToken); - } - - /// - public Task GetByIdAsync(TId id, CancellationToken cancellationToken = default) - { - return _sourceRepository.GetByIdAsync(id, cancellationToken); - } - - /// - public Task FirstOrDefaultAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - if (specification.CacheEnabled) - { - var key = $"{specification.CacheKey}-GetBySpecAsync"; - _logger.LogInformation("Checking cache for {cache_key}", key); - return _cache.GetOrCreate(key, entry => - { - entry.SetOptions(_cacheOptions); - _logger.LogWarning("Fetching source data for {cache_key}", key); + private readonly IMemoryCache _cache; + private readonly ILogger> _logger; + private readonly MyRepository _sourceRepository; + private readonly MemoryCacheEntryOptions _cacheOptions; + + public CachedRepository(IMemoryCache cache, + ILogger> logger, + MyRepository sourceRepository) + { + _cache = cache; + _logger = logger; + _sourceRepository = sourceRepository; + + _cacheOptions = new MemoryCacheEntryOptions() + .SetAbsoluteExpiration(relative: TimeSpan.FromSeconds(10)); + } + + /// + public virtual IAsyncEnumerable AsAsyncEnumerable(ISpecification specification) + { + return _sourceRepository.AsAsyncEnumerable(specification); + } + + /// + public Task AnyAsync(Specification.ISpecification specification, CancellationToken cancellationToken = default) + { + // TODO: Add Caching + return _sourceRepository.AnyAsync(specification, cancellationToken); + } + + /// + public Task AnyAsync(CancellationToken cancellationToken = default) + { + // TODO: Add Caching + return _sourceRepository.AnyAsync(cancellationToken); + } + + /// + public Task CountAsync(Specification.ISpecification specification, CancellationToken cancellationToken = default) + { + // TODO: Add Caching + return _sourceRepository.CountAsync(specification, cancellationToken); + } + + /// + public Task CountAsync(CancellationToken cancellationToken = default) + { + // TODO: Add Caching + return _sourceRepository.CountAsync(cancellationToken); + } + + /// + public Task GetByIdAsync(int id, CancellationToken cancellationToken = default) + { + return _sourceRepository.GetByIdAsync(id, cancellationToken); + } + + /// + public Task GetByIdAsync(TId id, CancellationToken cancellationToken = default) + { + return _sourceRepository.GetByIdAsync(id, cancellationToken); + } + + /// + public Task FirstOrDefaultAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + if (specification.CacheEnabled) + { + var key = $"{specification.CacheKey}-GetBySpecAsync"; + _logger.LogInformation("Checking cache for {cache_key}", key); + return _cache.GetOrCreate(key, entry => + { + entry.SetOptions(_cacheOptions); + _logger.LogWarning("Fetching source data for {cache_key}", key); + return _sourceRepository.FirstOrDefaultAsync(specification, cancellationToken); + }); + } return _sourceRepository.FirstOrDefaultAsync(specification, cancellationToken); - }); - } - return _sourceRepository.FirstOrDefaultAsync(specification, cancellationToken); - } - - /// - public Task GetBySpecAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - throw new NotImplementedException(); - } - - /// - public virtual async Task FirstOrDefaultAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - return await _sourceRepository.FirstOrDefaultAsync(specification, cancellationToken); - } - - /// - public virtual async Task SingleOrDefaultAsync(ISingleResultSpecification specification, CancellationToken cancellationToken = default) - { - return await _sourceRepository.SingleOrDefaultAsync(specification, cancellationToken); - } - - /// - public virtual async Task SingleOrDefaultAsync(ISingleResultSpecification specification, CancellationToken cancellationToken = default) - { - return await _sourceRepository.SingleOrDefaultAsync(specification, cancellationToken); - } - - /// - public Task> ListAsync(CancellationToken cancellationToken = default) - { - var key = $"{nameof(T)}-ListAsync"; - return _cache.GetOrCreate(key, entry => - { - entry.SetOptions(_cacheOptions); - return _sourceRepository.ListAsync(cancellationToken); - }); - } - - /// - public Task> ListAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - if (specification.CacheEnabled) - { - var key = $"{specification.CacheKey}-ListAsync"; - _logger.LogInformation("Checking cache for {cache_key}", key); - return _cache.GetOrCreate(key, entry => - { - entry.SetOptions(_cacheOptions); - _logger.LogWarning("Fetching source data for {cache_key}", key); + } + + /// + public Task GetBySpecAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + /// + public virtual async Task FirstOrDefaultAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + return await _sourceRepository.FirstOrDefaultAsync(specification, cancellationToken); + } + + /// + public virtual async Task SingleOrDefaultAsync(ISingleResultSpecification specification, CancellationToken cancellationToken = default) + { + return await _sourceRepository.SingleOrDefaultAsync(specification, cancellationToken); + } + + /// + public virtual async Task SingleOrDefaultAsync(ISingleResultSpecification specification, CancellationToken cancellationToken = default) + { + return await _sourceRepository.SingleOrDefaultAsync(specification, cancellationToken); + } + + /// + public Task> ListAsync(CancellationToken cancellationToken = default) + { + var key = $"{nameof(T)}-ListAsync"; + return _cache.GetOrCreate(key, entry => + { + entry.SetOptions(_cacheOptions); + return _sourceRepository.ListAsync(cancellationToken); + }); + } + + /// + public Task> ListAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + if (specification.CacheEnabled) + { + var key = $"{specification.CacheKey}-ListAsync"; + _logger.LogInformation("Checking cache for {cache_key}", key); + return _cache.GetOrCreate(key, entry => + { + entry.SetOptions(_cacheOptions); + _logger.LogWarning("Fetching source data for {cache_key}", key); + return _sourceRepository.ListAsync(specification, cancellationToken); + }); + } return _sourceRepository.ListAsync(specification, cancellationToken); - }); - } - return _sourceRepository.ListAsync(specification, cancellationToken); - } - - /// - public Task> ListAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - throw new NotImplementedException(); - } - - /// - public Task GetBySpecAsync(ISpecification specification, CancellationToken cancellationToken = default) - { - throw new NotImplementedException(); - } + } + + /// + public Task> ListAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + /// + public Task GetBySpecAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } } diff --git a/sample/Ardalis.SampleApp.Infrastructure/Data/CustomerRepository.cs b/sample/Ardalis.SampleApp.Infrastructure/Data/CustomerRepository.cs index be5ae5fc..d604f10d 100644 --- a/sample/Ardalis.SampleApp.Infrastructure/Data/CustomerRepository.cs +++ b/sample/Ardalis.SampleApp.Infrastructure/Data/CustomerRepository.cs @@ -11,18 +11,18 @@ namespace Ardalis.SampleApp.Infrastructure.Data; // This is just to demonstrate that at anytime you can create custom repositories, and use to create some complex queries working directly with EF or your ORM. public class CustomerRepository : ICustomerRepository { - private readonly SampleDbContext dbContext; + private readonly SampleDbContext dbContext; - public CustomerRepository(SampleDbContext dbContext) - { - this.dbContext = dbContext; - } + public CustomerRepository(SampleDbContext dbContext) + { + this.dbContext = dbContext; + } - public Task> GetCustomers(string addressSearchTerm) - { - return dbContext.Customers - .Take(10) - .Where(x => EF.Functions.Like(x.Address, "%" + addressSearchTerm + "%")) - .ToListAsync(); - } + public Task> GetCustomers(string addressSearchTerm) + { + return dbContext.Customers + .Take(10) + .Where(x => EF.Functions.Like(x.Address, "%" + addressSearchTerm + "%")) + .ToListAsync(); + } } diff --git a/sample/Ardalis.SampleApp.Infrastructure/Data/MyRepository.cs b/sample/Ardalis.SampleApp.Infrastructure/Data/MyRepository.cs index c4a26eba..f60f8279 100644 --- a/sample/Ardalis.SampleApp.Infrastructure/Data/MyRepository.cs +++ b/sample/Ardalis.SampleApp.Infrastructure/Data/MyRepository.cs @@ -7,12 +7,12 @@ namespace Ardalis.SampleApp.Infrastructure.Data; /// public class MyRepository : RepositoryBase, IRepository where T : class, IAggregateRoot { - private readonly SampleDbContext dbContext; + private readonly SampleDbContext dbContext; - public MyRepository(SampleDbContext dbContext) : base(dbContext) - { - this.dbContext = dbContext; - } + public MyRepository(SampleDbContext dbContext) : base(dbContext) + { + this.dbContext = dbContext; + } - // Not required to implement anything. Add additional functionalities if required. + // Not required to implement anything. Add additional functionalities if required. } diff --git a/sample/Ardalis.SampleApp.Infrastructure/DataAccess/Configurations/CustomerConfiguration.cs b/sample/Ardalis.SampleApp.Infrastructure/DataAccess/Configurations/CustomerConfiguration.cs index d2d6a753..828fc518 100644 --- a/sample/Ardalis.SampleApp.Infrastructure/DataAccess/Configurations/CustomerConfiguration.cs +++ b/sample/Ardalis.SampleApp.Infrastructure/DataAccess/Configurations/CustomerConfiguration.cs @@ -6,13 +6,13 @@ namespace Ardalis.SampleApp.Infrastructure.DataAccess.Configurations; public class CustomerConfiguration : IEntityTypeConfiguration { - public void Configure(EntityTypeBuilder builder) - { - builder.ToTable(nameof(Customer)); + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable(nameof(Customer)); - builder.Metadata.FindNavigation(nameof(Customer.Stores)) - .SetPropertyAccessMode(PropertyAccessMode.Field); + builder.Metadata.FindNavigation(nameof(Customer.Stores)) + .SetPropertyAccessMode(PropertyAccessMode.Field); - builder.HasKey(x => x.Id); - } + builder.HasKey(x => x.Id); + } } diff --git a/sample/Ardalis.SampleApp.Infrastructure/DataAccess/Configurations/StoreConfiguration.cs b/sample/Ardalis.SampleApp.Infrastructure/DataAccess/Configurations/StoreConfiguration.cs index bfe2efef..380782e8 100644 --- a/sample/Ardalis.SampleApp.Infrastructure/DataAccess/Configurations/StoreConfiguration.cs +++ b/sample/Ardalis.SampleApp.Infrastructure/DataAccess/Configurations/StoreConfiguration.cs @@ -6,10 +6,10 @@ namespace Ardalis.SampleApp.Infrastructure.DataAccess.Configurations; public class StoreConfiguration : IEntityTypeConfiguration { - public void Configure(EntityTypeBuilder builder) - { - builder.ToTable(nameof(Store)); + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable(nameof(Store)); - builder.HasKey(x => x.Id); - } + builder.HasKey(x => x.Id); + } } diff --git a/sample/Ardalis.SampleApp.Infrastructure/DataAccess/SampleDbContext.cs b/sample/Ardalis.SampleApp.Infrastructure/DataAccess/SampleDbContext.cs index 7333d199..c7d98f9a 100644 --- a/sample/Ardalis.SampleApp.Infrastructure/DataAccess/SampleDbContext.cs +++ b/sample/Ardalis.SampleApp.Infrastructure/DataAccess/SampleDbContext.cs @@ -6,18 +6,18 @@ namespace Ardalis.SampleApp.Infrastructure.DataAccess; public class SampleDbContext : DbContext { - public DbSet Customers { get; set; } + public DbSet Customers { get; set; } - public SampleDbContext(DbContextOptions options) - : base(options) - { - } + public SampleDbContext(DbContextOptions options) + : base(options) + { + } - protected override void OnModelCreating(ModelBuilder builder) - { - base.OnModelCreating(builder); + protected override void OnModelCreating(ModelBuilder builder) + { + base.OnModelCreating(builder); - builder.ApplyConfiguration(new CustomerConfiguration()); - builder.ApplyConfiguration(new StoreConfiguration()); - } + builder.ApplyConfiguration(new CustomerConfiguration()); + builder.ApplyConfiguration(new StoreConfiguration()); + } } diff --git a/sample/Ardalis.SampleApp.Infrastructure/DataAccess/SampleDbContextSeed.cs b/sample/Ardalis.SampleApp.Infrastructure/DataAccess/SampleDbContextSeed.cs index 74c16677..5ecbfd68 100644 --- a/sample/Ardalis.SampleApp.Infrastructure/DataAccess/SampleDbContextSeed.cs +++ b/sample/Ardalis.SampleApp.Infrastructure/DataAccess/SampleDbContextSeed.cs @@ -7,36 +7,36 @@ namespace Ardalis.SampleApp.Infrastructure.DataAccess; public class SampleDbContextSeed { - private readonly SampleDbContext dbContext; + private readonly SampleDbContext dbContext; - public SampleDbContextSeed(SampleDbContext dbContext) - { - this.dbContext = dbContext; - } - - public async Task SeedAsync(int retry = 0) - { - try + public SampleDbContextSeed(SampleDbContext dbContext) { - dbContext.Database.Migrate(); + this.dbContext = dbContext; + } - if (await dbContext.Customers.CountAsync() == 0) - { - foreach (var customer in CustomerSeed.Seed()) + public async Task SeedAsync(int retry = 0) + { + try { - dbContext.Customers.Add(customer); - } - } + dbContext.Database.Migrate(); - await dbContext.SaveChangesAsync(); + if (await dbContext.Customers.CountAsync() == 0) + { + foreach (var customer in CustomerSeed.Seed()) + { + dbContext.Customers.Add(customer); + } + } + await dbContext.SaveChangesAsync(); + + } + catch (Exception) + { + if (retry > 0) + { + await SeedAsync(retry - 1); + } + } } - catch (Exception) - { - if (retry > 0) - { - await SeedAsync(retry - 1); - } - } - } } diff --git a/sample/Ardalis.SampleApp.Infrastructure/Migrations/20201102224526_SampleDB-v1.cs b/sample/Ardalis.SampleApp.Infrastructure/Migrations/20201102224526_SampleDB-v1.cs index 905c6a77..637c74bd 100644 --- a/sample/Ardalis.SampleApp.Infrastructure/Migrations/20201102224526_SampleDB-v1.cs +++ b/sample/Ardalis.SampleApp.Infrastructure/Migrations/20201102224526_SampleDB-v1.cs @@ -4,56 +4,56 @@ namespace Ardalis.SampleApp.Infrastructure.Migrations; public partial class SampleDBv1 : Migration { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "Customer", - columns: table => new - { - Id = table.Column(nullable: false) - .Annotation("SqlServer:Identity", "1, 1"), - Name = table.Column(nullable: true), - Email = table.Column(nullable: true), - Address = table.Column(nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_Customer", x => x.Id); - }); + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Customer", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Name = table.Column(nullable: true), + Email = table.Column(nullable: true), + Address = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Customer", x => x.Id); + }); - migrationBuilder.CreateTable( - name: "Store", - columns: table => new - { - Id = table.Column(nullable: false) - .Annotation("SqlServer:Identity", "1, 1"), - Name = table.Column(nullable: true), - Address = table.Column(nullable: true), - CustomerId = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Store", x => x.Id); - table.ForeignKey( - name: "FK_Store_Customer_CustomerId", - column: x => x.CustomerId, - principalTable: "Customer", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); + migrationBuilder.CreateTable( + name: "Store", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Name = table.Column(nullable: true), + Address = table.Column(nullable: true), + CustomerId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Store", x => x.Id); + table.ForeignKey( + name: "FK_Store_Customer_CustomerId", + column: x => x.CustomerId, + principalTable: "Customer", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); - migrationBuilder.CreateIndex( - name: "IX_Store_CustomerId", - table: "Store", - column: "CustomerId"); - } + migrationBuilder.CreateIndex( + name: "IX_Store_CustomerId", + table: "Store", + column: "CustomerId"); + } - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "Store"); + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Store"); - migrationBuilder.DropTable( - name: "Customer"); - } + migrationBuilder.DropTable( + name: "Customer"); + } } diff --git a/sample/Ardalis.SampleApp.Web/AutomapperMaps.cs b/sample/Ardalis.SampleApp.Web/AutomapperMaps.cs index 63dacf0a..a1fdc69f 100644 --- a/sample/Ardalis.SampleApp.Web/AutomapperMaps.cs +++ b/sample/Ardalis.SampleApp.Web/AutomapperMaps.cs @@ -8,12 +8,12 @@ namespace Ardalis.SampleApp.Web; public class AutomapperMaps : Profile { - public AutomapperMaps() - { - CreateMap().IncludeAllDerived().ReverseMap(); - CreateMap().ReverseMap(); + public AutomapperMaps() + { + CreateMap().IncludeAllDerived().ReverseMap(); + CreateMap().ReverseMap(); - CreateMap(); - CreateMap(); - } + CreateMap(); + CreateMap(); + } } diff --git a/sample/Ardalis.SampleApp.Web/Controllers/CustomersController.cs b/sample/Ardalis.SampleApp.Web/Controllers/CustomersController.cs index b071d4f6..47162c72 100644 --- a/sample/Ardalis.SampleApp.Web/Controllers/CustomersController.cs +++ b/sample/Ardalis.SampleApp.Web/Controllers/CustomersController.cs @@ -10,35 +10,35 @@ namespace Ardalis.SampleApp.Web.Controllers; [Route("[controller]")] public class CustomersController : ControllerBase { - private readonly ICustomerUiService customerUiService; + private readonly ICustomerUiService customerUiService; - public CustomersController(ICustomerUiService customerUiService) - { - this.customerUiService = customerUiService; - } + public CustomersController(ICustomerUiService customerUiService) + { + this.customerUiService = customerUiService; + } - [HttpGet("{Id}")] - public Task Get(int Id) - { - return customerUiService.GetCustomer(Id); - } + [HttpGet("{Id}")] + public Task Get(int Id) + { + return customerUiService.GetCustomer(Id); + } - [HttpGet("{name}")] - public Task Get(string name) - { - return customerUiService.GetCustomer(name); - } + [HttpGet("{name}")] + public Task Get(string name) + { + return customerUiService.GetCustomer(name); + } - [HttpGet] - public Task> Get([FromQuery] CustomerFilterDto filter) - { - filter = filter ?? new CustomerFilterDto(); + [HttpGet] + public Task> Get([FromQuery] CustomerFilterDto filter) + { + filter = filter ?? new CustomerFilterDto(); - // Here you can decide if you want the collections as well + // Here you can decide if you want the collections as well - filter.LoadChildren = true; - filter.IsPagingEnabled = true; + filter.LoadChildren = true; + filter.IsPagingEnabled = true; - return customerUiService.GetCustomers(filter); - } + return customerUiService.GetCustomers(filter); + } } diff --git a/sample/Ardalis.SampleApp.Web/Interfaces/ICustomerUiService.cs b/sample/Ardalis.SampleApp.Web/Interfaces/ICustomerUiService.cs index a716e865..52727ec4 100644 --- a/sample/Ardalis.SampleApp.Web/Interfaces/ICustomerUiService.cs +++ b/sample/Ardalis.SampleApp.Web/Interfaces/ICustomerUiService.cs @@ -6,9 +6,9 @@ namespace Ardalis.SampleApp.Web.Interfaces; public interface ICustomerUiService { - Task GetCustomer(int customerId); - Task GetCustomer(string customerName); - Task GetCustomerWithStores(string customerName); + Task GetCustomer(int customerId); + Task GetCustomer(string customerName); + Task GetCustomerWithStores(string customerName); - Task> GetCustomers(CustomerFilterDto filterDto); + Task> GetCustomers(CustomerFilterDto filterDto); } diff --git a/sample/Ardalis.SampleApp.Web/Models/BaseFilterDto.cs b/sample/Ardalis.SampleApp.Web/Models/BaseFilterDto.cs index b969e098..c538991c 100644 --- a/sample/Ardalis.SampleApp.Web/Models/BaseFilterDto.cs +++ b/sample/Ardalis.SampleApp.Web/Models/BaseFilterDto.cs @@ -5,14 +5,14 @@ namespace Ardalis.SampleApp.Web.Models; public class BaseFilterDto { - [Browsable(false)] - [JsonIgnore] - public bool LoadChildren { get; set; } = false; + [Browsable(false)] + [JsonIgnore] + public bool LoadChildren { get; set; } = false; - [Browsable(false)] - [JsonIgnore] - public bool IsPagingEnabled { get; set; } = true; + [Browsable(false)] + [JsonIgnore] + public bool IsPagingEnabled { get; set; } = true; - public int Page { get; set; } = 1; - public int PageSize { get; set; } = 10; + public int Page { get; set; } = 1; + public int PageSize { get; set; } = 10; } diff --git a/sample/Ardalis.SampleApp.Web/Models/CustomerDto.cs b/sample/Ardalis.SampleApp.Web/Models/CustomerDto.cs index 8658881f..456de349 100644 --- a/sample/Ardalis.SampleApp.Web/Models/CustomerDto.cs +++ b/sample/Ardalis.SampleApp.Web/Models/CustomerDto.cs @@ -4,10 +4,10 @@ namespace Ardalis.SampleApp.Web.Models; public class CustomerDto { - public int Id { get; set; } - public string Name { get; set; } - public string Email { get; set; } - public string Address { get; set; } + public int Id { get; set; } + public string Name { get; set; } + public string Email { get; set; } + public string Address { get; set; } - public List Stores { get; set; } = new List(); + public List Stores { get; set; } = new List(); } diff --git a/sample/Ardalis.SampleApp.Web/Models/CustomerFilterDto.cs b/sample/Ardalis.SampleApp.Web/Models/CustomerFilterDto.cs index af2afd4e..2dba8243 100644 --- a/sample/Ardalis.SampleApp.Web/Models/CustomerFilterDto.cs +++ b/sample/Ardalis.SampleApp.Web/Models/CustomerFilterDto.cs @@ -2,7 +2,7 @@ public class CustomerFilterDto : BaseFilterDto { - public string Name { get; set; } - public string Email { get; set; } - public string Address { get; set; } + public string Name { get; set; } + public string Email { get; set; } + public string Address { get; set; } } diff --git a/sample/Ardalis.SampleApp.Web/Models/StoreDto.cs b/sample/Ardalis.SampleApp.Web/Models/StoreDto.cs index 340fa33e..f790a60f 100644 --- a/sample/Ardalis.SampleApp.Web/Models/StoreDto.cs +++ b/sample/Ardalis.SampleApp.Web/Models/StoreDto.cs @@ -2,7 +2,7 @@ public class StoreDto { - public int Id { get; set; } - public string Name { get; set; } - public string Address { get; set; } + public int Id { get; set; } + public string Name { get; set; } + public string Address { get; set; } } diff --git a/sample/Ardalis.SampleApp.Web/Pages/Index.cshtml.cs b/sample/Ardalis.SampleApp.Web/Pages/Index.cshtml.cs index b580dc45..1c0d68cd 100644 --- a/sample/Ardalis.SampleApp.Web/Pages/Index.cshtml.cs +++ b/sample/Ardalis.SampleApp.Web/Pages/Index.cshtml.cs @@ -11,25 +11,25 @@ namespace Ardalis.SampleApp.Web.Pages; public class IndexModel : PageModel { - private readonly IReadRepository _customerRepository; - private readonly ILogger _logger; + private readonly IReadRepository _customerRepository; + private readonly ILogger _logger; - public IndexModel(IReadRepository customerRepository, - ILogger logger) - { - _customerRepository = customerRepository; - _logger = logger; - } + public IndexModel(IReadRepository customerRepository, + ILogger logger) + { + _customerRepository = customerRepository; + _logger = logger; + } - public List Customers { get; set; } - public long ElapsedTimeMilliseconds { get; set; } + public List Customers { get; set; } + public long ElapsedTimeMilliseconds { get; set; } - public async Task OnGet() - { - var timer = Stopwatch.StartNew(); - var spec = new CustomerByNameWithStoresSpec(name: "Customer66"); - Customers = await _customerRepository.ListAsync(spec); - timer.Stop(); - ElapsedTimeMilliseconds = timer.ElapsedMilliseconds; - } + public async Task OnGet() + { + var timer = Stopwatch.StartNew(); + var spec = new CustomerByNameWithStoresSpec(name: "Customer66"); + Customers = await _customerRepository.ListAsync(spec); + timer.Stop(); + ElapsedTimeMilliseconds = timer.ElapsedMilliseconds; + } } diff --git a/sample/Ardalis.SampleApp.Web/Program.cs b/sample/Ardalis.SampleApp.Web/Program.cs index 419ca9e8..cafa2469 100644 --- a/sample/Ardalis.SampleApp.Web/Program.cs +++ b/sample/Ardalis.SampleApp.Web/Program.cs @@ -10,33 +10,33 @@ namespace Ardalis.SampleApp.Web; public class Program { - public static async Task Main(string[] args) - { - var host = CreateHostBuilder(args).Build(); - - using (var scope = host.Services.CreateScope()) + public static async Task Main(string[] args) { - var services = scope.ServiceProvider; - try - { - var dbContext = services.GetRequiredService(); + var host = CreateHostBuilder(args).Build(); - await new SampleDbContextSeed(dbContext).SeedAsync(); - } - catch (Exception) - { - } - } + using (var scope = host.Services.CreateScope()) + { + var services = scope.ServiceProvider; + try + { + var dbContext = services.GetRequiredService(); - host.Run(); - } + await new SampleDbContextSeed(dbContext).SeedAsync(); + } + catch (Exception) + { + } + } + + host.Run(); + } - public static IHostBuilder CreateHostBuilder(string[] args) => - Host.CreateDefaultBuilder(args) - .ConfigureWebHostDefaults(webBuilder => - { - webBuilder.ConfigureLogging(config => - config.AddConsole()); - webBuilder.UseStartup(); - }); + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.ConfigureLogging(config => + config.AddConsole()); + webBuilder.UseStartup(); + }); } diff --git a/sample/Ardalis.SampleApp.Web/Services/CustomerUiService.cs b/sample/Ardalis.SampleApp.Web/Services/CustomerUiService.cs index cd4a9281..1fe98986 100644 --- a/sample/Ardalis.SampleApp.Web/Services/CustomerUiService.cs +++ b/sample/Ardalis.SampleApp.Web/Services/CustomerUiService.cs @@ -13,51 +13,51 @@ namespace Ardalis.SampleApp.Web.Services; public class CustomerUiService : ICustomerUiService { - private readonly IMapper mapper; - private readonly IReadRepository customerRepository; + private readonly IMapper _mapper; + private readonly IReadRepository _customerRepository; - public CustomerUiService(IMapper mapper, - IReadRepository customerRepository) - { - this.mapper = mapper; - this.customerRepository = customerRepository; - } + public CustomerUiService(IMapper mapper, + IReadRepository customerRepository) + { + _mapper = mapper; + _customerRepository = customerRepository; + } - // Here I'm just writing various usages, not necessarily you'll need all of them. + // Here I'm just writing various usages, not necessarily you'll need all of them. - public async Task GetCustomer(int customerId) - { - var customer = await customerRepository.GetByIdAsync(customerId); + public async Task GetCustomer(int customerId) + { + var customer = await _customerRepository.GetByIdAsync(customerId); - Guard.Against.Null(customer, nameof(customer)); + Guard.Against.Null(customer, nameof(customer)); - return mapper.Map(customer); - } + return _mapper.Map(customer); + } - public async Task GetCustomer(string customerName) - { - var customer = await customerRepository.GetBySpecAsync(new CustomerByNameSpec(customerName)); + public async Task GetCustomer(string customerName) + { + var customer = await _customerRepository.GetBySpecAsync(new CustomerByNameSpec(customerName)); - Guard.Against.Null(customer, nameof(customer)); + Guard.Against.Null(customer, nameof(customer)); - return mapper.Map(customer); - } + return _mapper.Map(customer); + } - public async Task GetCustomerWithStores(string customerName) - { - var customer = await customerRepository.GetBySpecAsync(new CustomerByNameWithStoresSpec(customerName)); + public async Task GetCustomerWithStores(string customerName) + { + var customer = await _customerRepository.GetBySpecAsync(new CustomerByNameWithStoresSpec(customerName)); - Guard.Against.Null(customer, nameof(customer)); + Guard.Against.Null(customer, nameof(customer)); - return mapper.Map(customer); - } + return _mapper.Map(customer); + } - public async Task> GetCustomers(CustomerFilterDto filterDto) - { - var spec = new CustomerSpec(mapper.Map(filterDto)); - var customers = await customerRepository.ListAsync(spec); + public async Task> GetCustomers(CustomerFilterDto filterDto) + { + var spec = new CustomerSpec(_mapper.Map(filterDto)); + var customers = await _customerRepository.ListAsync(spec); - return mapper.Map>(customers); - } + return _mapper.Map>(customers); + } } diff --git a/sample/Ardalis.SampleApp.Web/Startup.cs b/sample/Ardalis.SampleApp.Web/Startup.cs index a1b2b70f..70b70f79 100644 --- a/sample/Ardalis.SampleApp.Web/Startup.cs +++ b/sample/Ardalis.SampleApp.Web/Startup.cs @@ -14,47 +14,47 @@ namespace Ardalis.SampleApp.Web; public class Startup { - public Startup(IConfiguration configuration) - { - Configuration = configuration; - } + public Startup(IConfiguration configuration) + { + Configuration = configuration; + } - public IConfiguration Configuration { get; } + public IConfiguration Configuration { get; } - // This method gets called by the runtime. Use this method to add services to the container. - public void ConfigureServices(IServiceCollection services) - { - services.AddDbContext(options => options.UseSqlServer(Configuration.GetConnectionString("MyDbConnection"))); + // This method gets called by the runtime. Use this method to add services to the container. + public void ConfigureServices(IServiceCollection services) + { + services.AddDbContext(options => options.UseSqlServer(Configuration.GetConnectionString("MyDbConnection"))); - services.AddAutoMapper(typeof(AutomapperMaps)); + services.AddAutoMapper(typeof(AutomapperMaps)); - services.AddScoped(typeof(IReadRepository<>), typeof(CachedRepository<>)); - services.AddScoped(typeof(MyRepository<>)); - services.AddScoped(); + services.AddScoped(typeof(IReadRepository<>), typeof(CachedRepository<>)); + services.AddScoped(typeof(MyRepository<>)); + services.AddScoped(); - // services.AddControllers(); - services.AddMvc(); - services.AddLogging(); - } + // services.AddControllers(); + services.AddMvc(); + services.AddLogging(); + } - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) - { - if (env.IsDevelopment()) + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { - app.UseDeveloperExceptionPage(); - } + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } - app.UseHttpsRedirection(); + app.UseHttpsRedirection(); - app.UseRouting(); + app.UseRouting(); - app.UseAuthorization(); + app.UseAuthorization(); - app.UseEndpoints(endpoints => - { - endpoints.MapControllers(); - endpoints.MapRazorPages(); - }); - } + app.UseEndpoints(endpoints => + { + endpoints.MapControllers(); + endpoints.MapRazorPages(); + }); + } }