Repository: dotnet/efcore
File: src/EFCore/Query/ExpressionEqualityComparer.cs (C#)

Code before:

                    break;

                case BlockExpression blockExpression:
                    AddListToHash(blockExpression.Variables);
                    AddListToHash(blockExpression.Expressions);
                    break;

                case ConditionalExpression conditionalExpression:
                    hash.Add(conditionalExpression.Test, this);
                    hash.Add(conditionalExpression.IfTrue, this);
                    hash.Add(conditionalExpression.IfFalse, this);
                    break;

                case ConstantExpression constantExpression:
                    switch (constantExpression.Value)
                    {
                        case IQueryable:
                        case null:
                            break;

                        case IStructuralEquatable structuralEquatable:
                            hash.Add(structuralEquatable.GetHashCode(StructuralComparisons.StructuralEqualityComparer));
                            break;

                        case IEnumerable enumerable when constantExpression.Value is not string:
                            foreach (var item in enumerable)
                            {
                                hash.Add(item);
                            }
                            break;

                        default:
                            hash.Add(constantExpression.Value);
                            break;
                    }

                    break;

                case DefaultExpression:
                    // Intentionally empty. No additional members
                    break;

                case GotoExpression gotoExpression:
                    hash.Add(gotoExpression.Value, this);
                    hash.Add(gotoExpression.Kind);
                    hash.Add(gotoExpression.Target);
                    break;

                case IndexExpression indexExpression:
                    hash.Add(indexExpression.Object, this);

Review comment (performance):
There are some limitations with this approach. At this point we don't have any information about the intent. In some cases we don't care about the order of elements in the collection, nor we care about the type of the collection. We just care that the elements are the same in no particular order.
 
With the implementation above we get the cache hit only when the type of the collection and order of the elements is the same.
For example:
```csharp
var result = context.Entities
    .IgnoreQueryFilters(["ActiveFilter", "NameFilter"])
    .ToList();
_ = context.Entities
    .IgnoreQueryFilters(["ActiveFilter", "NameFilter"])
    .ToList();
```

However, the following won't work:
```csharp
var result = context.Entities
    .IgnoreQueryFilters(["ActiveFilter", "NameFilter"])
    .ToList();
_ = context.Entities
    .IgnoreQueryFilters(["NameFilter", "ActiveFilter"])
    .ToList();
```

it will work with sorted collection for example
```csharp
var result = context.Entities
    .IgnoreQueryFilters(new SortedSet<string> { "ActiveFilter", "NameFilter" })
    .ToList();
_ = context.Entities
    .IgnoreQueryFilters(new SortedSet<string> { "NameFilter", "ActiveFilter" })
    .ToList();
```

The question is how to pass that information to the comparer that we care or not about the order. We only have a type information. If we are OK with this limitation, then fine

Code after:

                    break;

                case BlockExpression blockExpression:
                    AddListToHash(blockExpression.Variables);
                    AddListToHash(blockExpression.Expressions);
                    break;

                case ConditionalExpression conditionalExpression:
                    hash.Add(conditionalExpression.Test, this);
                    hash.Add(conditionalExpression.IfTrue, this);
                    hash.Add(conditionalExpression.IfFalse, this);
                    break;

                case ConstantExpression constantExpression:
                    switch (constantExpression.Value)
                    {
                        case IQueryable:
                        case null:
                            break;

                        case IStructuralEquatable structuralEquatable:
                            hash.Add(structuralEquatable.GetHashCode(StructuralComparisons.StructuralEqualityComparer));
                            break;

                        default:
                            hash.Add(constantExpression.Value);
                            break;
                    }

                    break;

                case DefaultExpression:
                    // Intentionally empty. No additional members
                    break;

                case GotoExpression gotoExpression:
                    hash.Add(gotoExpression.Value, this);
                    hash.Add(gotoExpression.Kind);
                    hash.Add(gotoExpression.Target);
                    break;

                case IndexExpression indexExpression:
                    hash.Add(indexExpression.Object, this);
                    AddListToHash(indexExpression.Arguments);
                    hash.Add(indexExpression.Indexer);
                    break;

                case InvocationExpression invocationExpression:
                    hash.Add(invocationExpression.Expression, this);
                    AddListToHash(invocationExpression.Arguments);