Skip to content

Add a fallback to LINQ for search evaluators/validator in case of custom user specifications. - #514

Merged
fiseni merged 3 commits into
mainfrom
fiseni/search-linq-fallback
Jun 14, 2025
Merged

Add a fallback to LINQ for search evaluators/validator in case of custom user specifications.#514
fiseni merged 3 commits into
mainfrom
fiseni/search-linq-fallback

Conversation

@fiseni

@fiseni fiseni commented Jun 13, 2025

Copy link
Copy Markdown
Collaborator

This is just to cover the case where users have a custom ISpecification<T> implementation but use our evaluator.
It's highly unlikely that anyone does that, but we'll add a fallback to LINQ for the sake of completeness.

@fiseni
fiseni requested a review from Copilot June 13, 2025 14:53

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds LINQ-based fallbacks for search operations when using custom ISpecification<T> implementations and updates tests to cover those scenarios.

  • Introduced fallback search logic in validator and evaluators for non-Specification<T> cases
  • Added span and enumerable overloads in EF Core SearchExtension and updated corresponding tests
  • Expanded test suite with custom-spec tests for validator, memory evaluator, and EF evaluator

Reviewed Changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/Ardalis.Specification/Validators/SearchValidator.cs Added fallback search logic for custom specifications
src/Ardalis.Specification/Evaluators/SearchMemoryEvaluator.cs Added LINQ-based fallback for memory evaluator
src/Ardalis.Specification.EntityFrameworkCore/Evaluators/SearchEvaluator.cs Added LINQ fallback using ApplyLikesAsOrGroup for EF evaluator
src/Ardalis.Specification.EntityFrameworkCore/Evaluators/SearchExtension.cs Introduced span/enumerable overloads and removed duplicate return
src/Ardalis.Specification/Ardalis.Specification.csproj Added InternalsVisibleTo for EF Core test assembly
tests/Ardalis.Specification.Tests/Validators/SearchValidatorCustomSpecTests.cs Added validator tests for custom specs
tests/Ardalis.Specification.Tests/Evaluators/SearchMemoryEvaluatorTests.cs Updated memory evaluator tests
tests/Ardalis.Specification.Tests/Evaluators/SearchMemoryEvaluatorCustomSpecTests.cs Added memory evaluator tests for custom specs
tests/Ardalis.Specification.EntityFrameworkCore.Tests/Evaluators/SearchExtensionTests.cs Updated EF Core extension tests to use new overloads
tests/Ardalis.Specification.EntityFrameworkCore.Tests/Evaluators/SearchEvaluatorCustomSpecTests.cs Added EF Core evaluator tests for custom specs
Comments suppressed due to low confidence (2)

src/Ardalis.Specification/Evaluators/SearchMemoryEvaluator.cs:29

  • The fallback in the memory evaluator applies only search expressions and ignores any custom WhereExpressions on a custom spec. Consider applying specification.WhereExpressions before the search fallback so custom where criteria are honored.
foreach (var searchGroup in specification.SearchCriterias.GroupBy(x => x.SearchGroup))

src/Ardalis.Specification.EntityFrameworkCore/Evaluators/SearchEvaluator.cs:33

  • The EF Core evaluator fallback only applies search groups and does not apply WhereExpressions from a custom spec. You may need to invoke the spec's where filters before executing the search fallback.
foreach (var searchGroup in specification.SearchCriterias.GroupBy(x => x.SearchGroup))

Comment thread src/Ardalis.Specification/Validators/SearchValidator.cs
Comment thread src/Ardalis.Specification/Validators/SearchValidator.cs Outdated
@fiseni
fiseni merged commit fc9b0a4 into main Jun 14, 2025
@fiseni
fiseni deleted the fiseni/search-linq-fallback branch June 14, 2025 14:19
This was referenced Aug 20, 2025
gritcsenko added a commit to gritcsenko/HomeInventory that referenced this pull request Aug 24, 2025
This PR contains the following updates:

| Package | Change | Age | Confidence |
|---|---|---|---|
|
[Ardalis.Specification](https://redirect.github.com/ardalis/specification)
| `9.2.0` -> `9.3.0` |
[![age](https://developer.mend.io/api/mc/badges/age/nuget/Ardalis.Specification/9.3.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/nuget/Ardalis.Specification/9.2.0/9.3.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>ardalis/specification (Ardalis.Specification)</summary>

###
[`v9.3.0`](https://redirect.github.com/ardalis/Specification/releases/tag/v9.3.0)

#### What's Changed

- Avoid List allocation for PostProcessingAction. by
[@&#8203;fiseni](https://redirect.github.com/fiseni) in
[ardalis/Specification#501](https://redirect.github.com/ardalis/Specification/pull/501)
- Redefine WithProjectionOf as an extension to Specification instead of
ISpecification by [@&#8203;fiseni](https://redirect.github.com/fiseni)
in
[ardalis/Specification#517](https://redirect.github.com/ardalis/Specification/pull/517)
- Rename TagWithEvaluator to QueryTagEvaluator. by
[@&#8203;fiseni](https://redirect.github.com/fiseni) in
[ardalis/Specification#512](https://redirect.github.com/ardalis/Specification/pull/512)
- OneOrMany implementation by
[@&#8203;fiseni](https://redirect.github.com/fiseni) in
[ardalis/Specification#507](https://redirect.github.com/ardalis/Specification/pull/507)
- Refactor the state of where expressions as OneOrMany. by
[@&#8203;fiseni](https://redirect.github.com/fiseni) in
[ardalis/Specification#508](https://redirect.github.com/ardalis/Specification/pull/508)
- Refactor the state of order expressions as OneOrMany. by
[@&#8203;fiseni](https://redirect.github.com/fiseni) in
[ardalis/Specification#509](https://redirect.github.com/ardalis/Specification/pull/509)
- Refactor the state of include expressions as OneOrMany. by
[@&#8203;fiseni](https://redirect.github.com/fiseni) in
[ardalis/Specification#510](https://redirect.github.com/ardalis/Specification/pull/510)
- Refactor the state of search expressions as OneOrMany. by
[@&#8203;fiseni](https://redirect.github.com/fiseni) in
[ardalis/Specification#511](https://redirect.github.com/ardalis/Specification/pull/511)
- Consolidate OneOrMany implementation and its usage. by
[@&#8203;fiseni](https://redirect.github.com/fiseni) in
[ardalis/Specification#513](https://redirect.github.com/ardalis/Specification/pull/513)
- Add a fallback to LINQ for search evaluators/validator in case of
custom user specifications. by
[@&#8203;fiseni](https://redirect.github.com/fiseni) in
[ardalis/Specification#514](https://redirect.github.com/ardalis/Specification/pull/514)
- Update dependencies. by
[@&#8203;fiseni](https://redirect.github.com/fiseni) in
[ardalis/Specification#526](https://redirect.github.com/ardalis/Specification/pull/526)
- Use opencover format for coverage reports. by
[@&#8203;fiseni](https://redirect.github.com/fiseni) in
[ardalis/Specification#503](https://redirect.github.com/ardalis/Specification/pull/503)
- Added Full Build workflow that publishes coverage reports. by
[@&#8203;fiseni](https://redirect.github.com/fiseni) in
[ardalis/Specification#504](https://redirect.github.com/ardalis/Specification/pull/504)
- Add benchmarks project. by
[@&#8203;fiseni](https://redirect.github.com/fiseni) in
[ardalis/Specification#505](https://redirect.github.com/ardalis/Specification/pull/505)
- Cleanup by [@&#8203;fiseni](https://redirect.github.com/fiseni) in
[ardalis/Specification#518](https://redirect.github.com/ardalis/Specification/pull/518)
- Add new test fixtures for EF6 provider. by
[@&#8203;fiseni](https://redirect.github.com/fiseni) in
[ardalis/Specification#519](https://redirect.github.com/ardalis/Specification/pull/519)
- Add tests for EF6 evaluators. by
[@&#8203;fiseni](https://redirect.github.com/fiseni) in
[ardalis/Specification#520](https://redirect.github.com/ardalis/Specification/pull/520)

**Full Changelog**:
<ardalis/Specification@v9.2.0...v9.3.0>

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/gritcsenko/HomeInventory).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MS44MS4yIiwidXBkYXRlZEluVmVyIjoiNDEuODIuNyIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->
gritcsenko added a commit to gritcsenko/HomeInventory that referenced this pull request Aug 24, 2025
…1239)

This PR contains the following updates:

| Package | Change | Age | Confidence |
|---|---|---|---|
|
[Ardalis.Specification.EntityFrameworkCore](https://redirect.github.com/ardalis/specification)
| `9.2.0` -> `9.3.0` |
[![age](https://developer.mend.io/api/mc/badges/age/nuget/Ardalis.Specification.EntityFrameworkCore/9.3.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/nuget/Ardalis.Specification.EntityFrameworkCore/9.2.0/9.3.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>ardalis/specification
(Ardalis.Specification.EntityFrameworkCore)</summary>

###
[`v9.3.0`](https://redirect.github.com/ardalis/Specification/releases/tag/v9.3.0)

#### What's Changed

- Avoid List allocation for PostProcessingAction. by
[@&#8203;fiseni](https://redirect.github.com/fiseni) in
[ardalis/Specification#501](https://redirect.github.com/ardalis/Specification/pull/501)
- Redefine WithProjectionOf as an extension to Specification instead of
ISpecification by [@&#8203;fiseni](https://redirect.github.com/fiseni)
in
[ardalis/Specification#517](https://redirect.github.com/ardalis/Specification/pull/517)
- Rename TagWithEvaluator to QueryTagEvaluator. by
[@&#8203;fiseni](https://redirect.github.com/fiseni) in
[ardalis/Specification#512](https://redirect.github.com/ardalis/Specification/pull/512)
- OneOrMany implementation by
[@&#8203;fiseni](https://redirect.github.com/fiseni) in
[ardalis/Specification#507](https://redirect.github.com/ardalis/Specification/pull/507)
- Refactor the state of where expressions as OneOrMany. by
[@&#8203;fiseni](https://redirect.github.com/fiseni) in
[ardalis/Specification#508](https://redirect.github.com/ardalis/Specification/pull/508)
- Refactor the state of order expressions as OneOrMany. by
[@&#8203;fiseni](https://redirect.github.com/fiseni) in
[ardalis/Specification#509](https://redirect.github.com/ardalis/Specification/pull/509)
- Refactor the state of include expressions as OneOrMany. by
[@&#8203;fiseni](https://redirect.github.com/fiseni) in
[ardalis/Specification#510](https://redirect.github.com/ardalis/Specification/pull/510)
- Refactor the state of search expressions as OneOrMany. by
[@&#8203;fiseni](https://redirect.github.com/fiseni) in
[ardalis/Specification#511](https://redirect.github.com/ardalis/Specification/pull/511)
- Consolidate OneOrMany implementation and its usage. by
[@&#8203;fiseni](https://redirect.github.com/fiseni) in
[ardalis/Specification#513](https://redirect.github.com/ardalis/Specification/pull/513)
- Add a fallback to LINQ for search evaluators/validator in case of
custom user specifications. by
[@&#8203;fiseni](https://redirect.github.com/fiseni) in
[ardalis/Specification#514](https://redirect.github.com/ardalis/Specification/pull/514)
- Update dependencies. by
[@&#8203;fiseni](https://redirect.github.com/fiseni) in
[ardalis/Specification#526](https://redirect.github.com/ardalis/Specification/pull/526)
- Use opencover format for coverage reports. by
[@&#8203;fiseni](https://redirect.github.com/fiseni) in
[ardalis/Specification#503](https://redirect.github.com/ardalis/Specification/pull/503)
- Added Full Build workflow that publishes coverage reports. by
[@&#8203;fiseni](https://redirect.github.com/fiseni) in
[ardalis/Specification#504](https://redirect.github.com/ardalis/Specification/pull/504)
- Add benchmarks project. by
[@&#8203;fiseni](https://redirect.github.com/fiseni) in
[ardalis/Specification#505](https://redirect.github.com/ardalis/Specification/pull/505)
- Cleanup by [@&#8203;fiseni](https://redirect.github.com/fiseni) in
[ardalis/Specification#518](https://redirect.github.com/ardalis/Specification/pull/518)
- Add new test fixtures for EF6 provider. by
[@&#8203;fiseni](https://redirect.github.com/fiseni) in
[ardalis/Specification#519](https://redirect.github.com/ardalis/Specification/pull/519)
- Add tests for EF6 evaluators. by
[@&#8203;fiseni](https://redirect.github.com/fiseni) in
[ardalis/Specification#520](https://redirect.github.com/ardalis/Specification/pull/520)

**Full Changelog**:
<ardalis/Specification@v9.2.0...v9.3.0>

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/gritcsenko/HomeInventory).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MS44MS4yIiwidXBkYXRlZEluVmVyIjoiNDEuODIuNyIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants