Microsoft.CodeAnalysis.FxCopAnalyzers
v2.9.8 (latest release)
Example: CA1307
new DbContext().MyEntities.Where(x => x.Name.StartsWith("Hello"))
No diagnostic is reported; actual comparison is done inside SQL so the "thread" is not relevant (I think).
Issue CA1307 is reported, suggesting "StartsWith(string, StringComparison)":
The behavior of 'string.StartsWith(string)' could vary based on the current user's locale settings. Replace this call in '...' with a call to 'string.StartsWith(string, System.StringComparison)'.
However that suggestion fails at runtime:
System.NotSupportedException: 'LINQ to Entities does not recognize the method 'Boolean StartsWith(System.String, System.StringComparison)' method, and this method cannot be translated into a store expression.'
actual comparison is done inside SQL so the "thread" is not relevant (I think).
That is correct, your lambda is sent as an Expression, not as actual executable code, and EF/LinqToSql parses the expression tree to build its own Sql expression. If possible, these checks should absolutely not run on expression parsers like these.
Also ran into this same suggestion. I would prefer to err on the side of caution, and if this is found within the bounds of an IQueryable, the check should move on.
You guys find the most creative way around this?
I'm thinking GlobalSupression.cs to just skip CA1307 altogether until it can be resolved in a better way.
Let me try to see if I can find how to fix this behavior.
A lot of these analyzers should probably be disabled for Expression<Func<T...> while enabled for Func<T...> as Roslyn can't possibly know enough about what the LINQ provider is going to do with the expression tree in the former.
(Title on this bug should probably be just changed to LINQ as it's a provider-independent problem and indeed the error message indicates that Entity Framework's LINQ is being used not the legacy LINQ to SQL)
@damieng can you think of any case that would be covered by excluding Expression<Func<T...>> which wouldn't be covered by checking that the IQueryable?
Expressions aren't tied to IQueryable and I can think of a number of scenarios where you might have standalone expressions - a comprehensive unit test suite for a LINQ provider might look at translation of expression parts themselves independently of IQueryable.
Is there some limitation in the analyzer that makes it harder for it to ignore Expression
I don't think it is any harder, I was just trying to add a meaningful test that would prevent the analyzer to be changed in the future. I will just add a call to some dummy method taking Expression<Func<T...>>.