EF Core 7+ 中的 STRING_AGG

问题描述 投票:0回答:1

我正在尝试在 SQL Server 端使用

STRING_AGG
。根据文档,从 EF Core 7.0 开始,

string.Join(separator, group.Select(x => x.Property)) 

应该翻译成

STRING_AGG(Property, @separator)
,但这个翻译没有发生。

我在这里缺少什么?

这是我的代码:

var names = _context.Account
                    .Select(l => new
                                 {                 
                                     Names = string.Join(" | ", l.Customers.Select(x=>x.FirstName))
                                 }).ToListAsync();

但是,被翻译成这个查询

SELECT  
    [t].[AccountId], [c].[FirstName], [c].[CustomerID]
FROM 
    (          FROM [Accounts] AS [l]
    ) AS [t]
LEFT JOIN 
    [Customer] AS [c] ON [t].[AccountId]= [c].[AccountId]

虽然我期待看到

SELECT
    STRING_AGG([c].[FirstName], N' | ')
FROM 
    [Customer] AS [c]
WHERE 
    [l].[AccountId] = [c].[AccountId]) AS [Names]
    FROM [Accounts] AS [l]
entity-framework-core
1个回答
0
投票

看起来

STRING_AGG
被设计为用作分组查询的一部分。这就是它在 EF Core 中的实现方式。但是,我们可以通过使用常量键进行分组来模仿此功能。例如:

EF Core 中的以下查询会生成

STRING_AGG
SQL,但生成的 SQL 可能看起来有问题:

var query = _context.Accounts
    .SelectMany(a => a.Customers)
    .GroupBy(c => 1) // Grouping by a constant
    .Select(g => new
    {
        Names = string.Join(", ", g.Select(c => c.FirstName))
    });

生成的SQL:

SELECT COALESCE(STRING_AGG([t].[FirstName], N', '), N'') AS [Names]
FROM (
    SELECT [c].[FirstName], 1 AS [Key]
    FROM [Accounts] AS [a]
    INNER JOIN [Customers] AS [c] ON [a].[Id] = [c].[AccountId]
) AS [t]
GROUP BY [t].[Key]

虽然这种方法有效,但通过使用有意义的非常量键进行分组可以获得更好的结果。例如:

var query = _context.Accounts
    .SelectMany(a => a.Customers)
    .GroupBy(c => c.AccountId) // Grouping by AccountId
    .Select(g => new
    {
        Names = string.Join(", ", g.Select(c => c.FirstName))
    });

生成的SQL:

SELECT COALESCE(STRING_AGG([c].[FirstName], N', '), N'') AS [Names]
FROM [Accounts] AS [a]
INNER JOIN [Customers] AS [c] ON [a].[Id] = [c].[AccountId]
GROUP BY [c].[AccountId]
© www.soinside.com 2019 - 2024. All rights reserved.