-
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
Distinct string.Join or string.Concat causing SQL Syntax error #29845
Comments
Unfortunately, SQL Server's STRING_AGG doesn't seem to support DISTINCT (most other aggregate functions do): DROP TABLE IF EXISTS [Blogs];
CREATE TABLE [Blogs] (
[Id] int NOT NULL IDENTITY,
[Category] int,
[Name] nvarchar(max)
);
INSERT INTO Blogs (Category, Name) VALUES (1, 'foo'), (1, 'bar');
SELECT STRING_AGG(DISTINCT (b.Name), N', ')
FROM Blogs AS b
GROUP BY b.Category; We should ideally fail translation rather than generate invalid SQL, but otherwise there's not much for us to do here... |
It is possible to do this with DROP TABLE IF EXISTS [Blogs];
CREATE TABLE [Blogs] (
[Id] int NOT NULL IDENTITY,
[Category] int,
[Name] nvarchar(max)
);
INSERT INTO Blogs (Category, Name) VALUES (1, 'foo'), (1, 'bar'), (2, 'baz');
SELECT STRING_AGG(tmp.Name, N', ')
FROM Blogs AS b
OUTER APPLY (
SELECT DISTINCT b2.Name AS Name
FROM Blogs b2
WHERE b2.Id = b.Id
) tmp
GROUP BY b.Category; |
@2767mr yeah, that's definitely possible - but we generally don't do such complicated things in method translations. Note that you can achieve a very similar thing via the following: _ = ctx.Blogs
.Select(b => new
{
b.Url,
PostTitles = string.Join(", ", b.Posts.Select(p => p.Title).Distinct())
})
.ToList(); This starts with the Blogs instead of the Posts, thus avoiding the need for a GroupBy altogether. The SQL it generates indeed uses an OUTER APPLY: SELECT [b].[Url], [b].[Id], [t].[Title]
FROM [Blogs] AS [b]
OUTER APPLY (
SELECT DISTINCT [p].[Title]
FROM [Posts] AS [p]
WHERE [b].[Id] = [p].[BlogId]
) AS [t]
ORDER BY [b].[Id] Importantly, EF doesn't translate to STRING_AGG in this context (aggregate function without groupby, #29200), so this is client-evaluated instead: the titles are pulled back from the database and joined via .NET string.Join. This isn't a problem in this particularly query (note that no extra data is being transferred as a result of the client eval), but does mean that you can't further compose LINQ operators on top of the query for execution in the database. |
Note from triage: we should throw a better exception here. |
While trying to work around #29200 using groupBy we discovered that the combination of
.Distinct()
andstring.Join
orstring.Concat
causes a SQL Syntax error. This issue seems similar to #29638.Example Query
Full project: https://github.com/2767mr/EFAggregateExample
Generated SQL:
Stacktrace:
Provider and version information
EF Core version: 7.0.1
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: .NET 6.0
Operating system: Windows 11
IDE: Visual Studio 2022
The text was updated successfully, but these errors were encountered: