-
Notifications
You must be signed in to change notification settings - Fork 3.2k
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
Create DiagnosticSuppressor for CS8602 in Linq expressions and Includes #21663
Comments
Related to #21608 |
This may not be a good idea. While I understand the logic behind it, it is hard to tell if the LINQ query is being run over EF here null safety won't matter vs objects where code which is null unsafe will certainly throw an error if evaluated. |
@smitpatel |
I'm guessing/hoping there are some cases where we can unambiguously determine we're in an EF-evaluated expression (at least in Includes as @Dreamescaper suggested, possibly even other cases)... We can look into this. |
For Linq case - we can try suppression only when expression starts with DbSet. await dbContext.Users
.Where(u => u => u.FirstName.Contains(searchTerm)
|| u.MiddleName.Contains(searchTerm) // <---------- query starts from DbSet<User>, suppress warning
|| u.LastName.Contains(searchTerm))
.ToListAsync(); but IQueryable<UserProfile> SearchQuery(IQueryable<User> query, string searchTerm)
{
return query.Where(up => up.FirstName.Contains(searchTerm)
|| up.MiddleName.Contains(searchTerm) // <------------ can't know if IQueryable is EF Core specific, so do not suppress warning
|| up.LastName.Contains(searchTerm);
} |
Note from triage: we're not going to put any DiagnosticSuppressors in for 5.0. We should discuss post-5.0 whether this is something that we should invest in. |
@ajcvikers Are there any plans for this suppressor? I'm interested to implement it and submit a PR. |
@Youssef1313 we don't have any concrete plans for implementing this soon (because of priorities). We'd welcome a community contribution, but as this is about code analysis it's best to start off with a quick and informal spec of exactly what you plan on doing, to make sure we're all on the same page. |
@roji I'd check the diagnostic location, and borrow the following method from roslyn-analyzers repo: and report a suppression if both of the following applies:
|
While there are indeed a few EF-specific methods where we can just suppress (e.g. Include), the interesting cases are general IQueryable operators (e.g. Where) which aren't EF-specific. In theory, we'd verify that the operator is rooted on an EF Core DbSet, though the likelihood of another LINQ provider in the same project is very low (can the user disable the suppression in that case via .editorconfig or something?). Needless to say, diagnostics in non-queryable LINQ to Objects should not be suppressed. @smitpatel @ajcvickers thoughts? |
I'm not aware of that (probably @mavasani or @sharwell knows?), but even if there is a way. I think the suppressor should not suppress correct CS8602. Either it works correctly in almost all cases, or leaves CS8602 warnings that are considered incorrect warnings. But it should not hide correct warnings. (i.e. false negatives are okay, but false positives are not). A false negative will lead to the user getting CS8602 and having to manually suppress it. But a false positive will hide a warning that shouldn't be hidden. |
I agree with that - any correct suppressions we do are useful (even if we don't cover all cases), but we shouldn't incorrectly suppress any diagnostic. |
@roji Does working with the solution require the current preview version of Visual Studio or any special requirements? I'm getting several warnings with VS 16.8: |
Did you follow this guide? https://www.github.com/dotnet/efcore/tree/main/docs%2Fgetting-and-building-the-code.md |
Design discussion:
|
@roji With the current Roslyn APIs, I can't see a way to have a suppression disabled by default to be opt-in. But that sounds like a reasonable feature request for Roslyn. Opened dotnet/roslyn#51278 for that in Roslyn. |
@Youssef1313 the suppressor can simply decide not to call ReportSuppression based on some flag in .editorconfig or elsewhere, no? |
A quick look seems to show that a suppressor cannot report new diagnostics, nor mutate existing ones - only suppress. |
Design decision: as there's no way for a suppressor to report new diagnostics, we'll suppress these warnings in all DbSet-rooted expression trees by default. An .editorconfig opt-in should allow opting back in to the warnings, effectively disabling the suppressor. @Youssef1313 I think we know what we want to do here - you can continue work on this. |
Actually, it seems like standard rules (editorconfig or XML) can be used to disable suppressions: https://github.com/nunit/nunit.analyzers/pull/325/files#diff-47f25205db28dc2d9aebf924f1be9ba85b2d18fbcedb7cad85710a371ec3468aR80 |
Currently CS8602 (Dereference of possibly null reference) is triggered for nullable properties in linq expressions, even though no NRE possible when query is executed on DB side.
Example 1 (Linq):
Example 2 (Includes):
Suggestion:
Create DiagnosticSuppressor for CS8602 for IQueryable expressions in Linq methods and for Include/ThenInclude methods.
The text was updated successfully, but these errors were encountered: