-
Notifications
You must be signed in to change notification settings - Fork 280
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
Convert a "Not Any" query for a condition to a "All" query for the inverted condition #31
Comments
In case of Linq To EF !Categories.Any(x => x.CategoryID > 5) generates the following SQL SELECT
CASE WHEN ( EXISTS (SELECT
1 AS [C1]
FROM [dbo].[Categories] AS [Extent1]
WHERE [Extent1].[CategoryID] > 5
)) THEN cast(1 as bit) WHEN ( NOT EXISTS (SELECT
1 AS [C1]
FROM [dbo].[Categories] AS [Extent2]
WHERE [Extent2].[CategoryID] > 5
)) THEN cast(0 as bit) END AS [C1]
FROM ( SELECT 1 AS X ) AS [SingleRowTable1] and the equivalent All version Categories.All(x => x.CategoryID <= 5) generates SELECT
CASE WHEN ( NOT EXISTS (SELECT
1 AS [C1]
FROM [dbo].[Categories] AS [Extent1]
WHERE ( NOT ([Extent1].[CategoryID] <= 5)) OR (CASE WHEN ([Extent1].[CategoryID] <= 5) THEN cast(1 as bit) WHEN ( NOT ([Extent1].[CategoryID] <= 5)) THEN cast(0 as bit) END IS NULL)
)) THEN cast(1 as bit) WHEN ( EXISTS (SELECT
1 AS [C1]
FROM [dbo].[Categories] AS [Extent2]
WHERE ( NOT ([Extent2].[CategoryID] <= 5)) OR (CASE WHEN ([Extent2].[CategoryID] <= 5) THEN cast(1 as bit) WHEN ( NOT ([Extent2].[CategoryID] <= 5)) THEN cast(0 as bit) END IS NULL)
)) THEN cast(0 as bit) END AS [C1]
FROM ( SELECT 1 AS X ) AS [SingleRowTable1] maybe the user wants having more control of generated SQL. |
You suggest that we favor a dynamically generated query in the EF rather suggest an improvement on code readability? If the dev wants more control over how EF generate query he can only ignore the code-cracker suggestion. |
Countless times I've sacrificed code readability over performance, and I think it's a rather common scenario. Perhaps this should be presented as an Info. |
I do prefer readability where there is no high perfomance reason. Maybe somebody dont. I could be info over DbSet, and another category over other objects. |
I understand that readability may not be a priority according to the scenario. But, then again, I understand that this is only a matter of deliberately ignore the suggestion made by code-cracker, as well as we can do in resharper. |
Agreed, it should be an And I love the idea. The problem is inverting the condition would probably result in this: if (!results.Any(r => r > 0))
throw new Exception("Error"); becoming: if (results.All(r => (r > 0) == false))
throw new Exception("Error"); We could treat specially the |
I don't think it should behave different for DbSet than for others. |
|
Ok... agreed with IQueryable. |
So, is this a |
I agree with that. |
Ok, I updated the description. Summarizing:
|
Not sure if this is true... I believe that All fails on the first occurrence that doesn't match. You're sure. |
I did a test... All stops as soon as it finds an occorrence that fails to match the condition. |
Not Any will be better in half of cases. All will be better on another half of cases. |
Perfect, @andersonaap. Now we have a problem. This cannot be a warning then even for |
That should be the case, alright. |
BCL could have a None extension where it would be equivalent to Not Any. |
So, a refactoring or a |
Seems to be a refactoring... it is as useful as invert an if (idk if anyone suggest that also) but now it is clear to me that is definitely not a code issue. |
Ok, it is marked as ready, anyone can start working on it, it is up for grabs, just let us know here in the comments so we don't have two people working at the same time. |
I can work on it. Excited to contribute. :) |
Go ahead, @moreirayokoyama! |
@moreirayokoyama, it is yours. I am changing the status to |
@moreirayokoyama How is this coming? Any idea when it will be done? |
@moreirayokoyama We just changed refactorings to be diagnostics+code fixes (see #66). |
I plan to finish it between today and tomorrow. I had unexpected issues last week that made me unable to finish it then. I'll make it diagnostic+code fix as well. Sorry. |
Ok, I'm trying to make more then just get any arbitrary "Any" method invocation and make sure that is the Any for an IEnumerable or IQueryable... but it is being hard to find out how to query the types in Roslyn. I searched in other analyzer but as it seems more assertive (by looking for methods like Single, First, SingleOrDefault etc) it seems pretty safe to assume. |
Yes, I think I can help you tomorrow. Let's try to talk, you have my email address. |
@moreirayokoyama Are you still planing to work on this one? |
@moreirayokoyama I am assuming you are not working on this one and returning it to the backlog. If you would like to complete let us know! |
I finished and added Any to All, and All to Any. Also added a lot of special cases. Check out: code-cracker/test/CSharp/CodeCracker.Test/Refactoring/ChangeAnyToAllTests.cs Lines 84 to 178 in 7b4bac8
|
Scenario 1: simple condition
This:
Becomes:
or
Scenario 2: special case
>
,<
,>=
and<=
This:
Becomes:
So it became more readable.
This is a refactoring, there is no diagnostic.
This is essentially a refactoring, so we are classifying it as a
Hidden
diagnostic.Category is
Refactoring
.Diagnostic id is:
CC0043
The text was updated successfully, but these errors were encountered: