New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ExpressionEqualityComparer.GetHashCode
not consistent with ExpressionEqualityComparer.Equals
#30697
Comments
Note that Equals disregards parameter names only for lambda parameters. For captured variables it doesn't ignore them; the logic is that captured variable names end up in the actual SQL (as the SQL parameter name), but lambda names really are meaningless when translating to SQL etc. It's true that GetHashCode could also track parameter scopes and take the name into account only for lambda parameters. This would allow two queries whose only different is a lambda parameter name to be considered the same in the query cache, slightly improving perf (in theory). Or are you seeing an additional problem here, such as an actual bug in EF behavior? |
@roji Thank you for the quick response.
I'm actually using This very issue is causing the specific part of my app that's using And even though "correctness" could be thought of as the main concern here, you're also right that fixing this would also theoretically improve EF's performance in some specific cases, since a LINQ query with an identical expression to a previous one, but with different parameter names, would result in a cache hit, as it should, I would argue, because as you yourself said:
And therefore they shouldn't be part of the query cache key; currently, however, they effectively are. |
Note that I don't think ExpressionEqualityComparer was meant for use as a general expression tree comparison facility, to be used externally. For example, lambda parameter names may not be important for EF, but it may be very important in other context; so ExpressionEqualityComparer fits EF's needs. Regardless, I agree about the principle of GetHashCode behaving like Equals here, and not taking into account lambda parameter names - though I wouldn't say it's very high priority. Are you interested in submitting a PR to fix this? |
@aradalvand ping |
Sorry I missed this.
Sure, will give it a try. |
The `GetHashCode` now bases the hash code of each parameter expression on its position in the containing lambda(s) parameter list, thereby making it so that otherwise identical lambda expressions whose only difference is the parameter names to yield the same hash code. Fixes dotnet#30697
When the parameter names of two otherwise identical expressions are different,
ExpressionEqualityComparer.Equals
returns true whereasExpressionEqualityComparer.GetHashCode
returns different results for the two expressions:Output:
If the parameter names had been the same,
GetHashCode
would return the same value for both expressions.Expected behavior: Unless there's something I'm missing, the
GetHashCode
algorithm shouldn't be dependent on the names of the parameters, just like theEquals
algorithm isn't. The two should be consistent in this regard.The text was updated successfully, but these errors were encountered: