如何使用 Entity Framework Core 将 STRING_AGG 强制转换为 varchar(max)

Dip*_*Dip 2 c# linq sql-server sql-to-linq-conversion entity-framework-core

我正在尝试使用 C# 中的 Entity Framework Core 和 Linq 来获取查询的以下部分

STRING_AGG(cast(EntityName as varchar(max)), ' , ') AS AllEntityNames
Run Code Online (Sandbox Code Playgroud)

我需要连接所有的EntityName. 但是,我收到错误:

STRING_AGG 聚合结果超出了 8000 字节的限制。使用 LOB 类型以避免结果截断。

当我使用时

.Select(g => new
             {
                 AllEntityNames = string.Join(",", g.Select(p => p.EntityName )) 
             })
Run Code Online (Sandbox Code Playgroud)

varchar我们如何在 C# 代码中对 SQL 查询的一部分进行转换?

T N*_*T N 5

一点背景知识:如果聚合输入STRING_AGG()VARCHAR(N)orNVARCHAR(N)类型,则结果类型分别限制为VARCHAR(8000)or NVARCHAR(4000)。如果结果更长,则会出现已发布的错误。

为了允许更长的结果,输入字符串必须转换为xVARCHAR(MAX)类型(在错误消息中称为“LOB 类型”)。问题是:我们如何从 LINQ to SQL 和 EF Core 做到这一点。

根据Microsoft SQL Server Provider文章的函数映射,函数调用Convert.ToString(value)将映射到CONVERT(nvarchar(max), @value).

这可能适用于字符串以外的类型的转换,但也适用于字符串类型。

您的代码将类似于:

.Select(g => new {
    // The Convert.ToString() below will cast EntityName to NVARCHAR(MAX).
    // This will avoid the 8000 char limit for STRING_AGG() on VARCHAR(N).
    // This comment is here for a reason. Leave it and the ToString() call.
    AllEntityNames = string.Join(
        ",",
        g.Select(p => Convert.ToString(p.EntityName))
    ) 
})
Run Code Online (Sandbox Code Playgroud)