我正在try 使用Npgsql将PostgreSQL查询转换为Linq:

var result = _dbContext.Substrates.FromSql(@$"SELECT 
                                                vs.*,
                                                STRING_AGG(DISTINCT p.product_ref, ', ') AS product_ref,
                                                STRING_AGG(DISTINCT cu.acr, ', ') AS acr
                                            FROM 
                                                portal_data.v_substrates vs
                                            LEFT JOIN portal_data.custart c ON c.article_id = vs.id_substrate
                                            LEFT JOIN portal_data.product_components pc ON pc.id_component = vs.id_substrate
                                            LEFT JOIN portal_data.products p ON p.id_product = pc.id_product
                                            LEFT JOIN portal_data.customers cu ON cu.id_customer = c.id_customer
                                            WHERE
                                                c.id_customer = {customerId}
                                            GROUP BY
                                                vs.id_substrate,
                                                vs.substrate_type,
                                                vs.substrate_creation_date,
                                                vs.substrate_status,
                                                vs.substrate_invent_qty,
                                                vs.record_copy_date,
                                                vs.mapped_status
                                            ");

根据Npgsql documentation,有一个名为EF.Functions.StringToArray()的翻译函数,如果我理解正确的话,它翻译成string_agg(s, '|').

var substrates = from substrate in _dbContext.Substrates
                 join custart in _dbContext.CustomerArticles on substrate.IdSubstrate equals custart.ArticleId
                 join component in _dbContext.ProductComponents on substrate.IdSubstrate equals component.IdComponent
                 join product in _dbContext.Products on component.IdProduct equals product.IdProduct
                 join customer in _dbContext.Customers on custart.IdCustomer equals customer.Id                              
                 where custart.IdCustomer == customerId
                 select new SubstrateExtended
                 {
                     IdSubstrate = substrate.IdSubstrate,
                     SubstrateType = substrate.SubstrateType,
                     SubstrateCreationDate = substrate.SubstrateCreationDate,
                     SubstrateStatus = substrate.SubstrateStatus,
                     SubstrateInvetoryQuantity = substrate.SubstrateInvetoryQuantity,
                     RecordCopyDate = substrate.RecordCopyDate,
                     MappedStatus = substrate.MappedStatus,
                     ProductRef = EF.Functions.StringToArray(product.ProductRef, ", "),
                     Acr = EF.Functions.StringToArray(customer.Accronym, ", ")
                 };

但这不起作用,因为EF.Functions.StringToArray()返回string[].

有没有一种方法可以将SQL查询转换为Linq,而不需要检索用于聚合的全部项目列表?

推荐答案

当量为string.Join,其中第二个参数为IEnumerable<string>.

但是您也遗漏了group by,并且您在原始查询中的连接是left join.

var substrates =
    from substrate in _dbContext.Substrates
    join custart1 in _dbContext.CustomerArticles on substrate.IdSubstrate equals custart.ArticleId into j1 from custart in j1.DefaultIfEmpty()
    join component1 in _dbContext.ProductComponents on substrate.IdSubstrate equals component.IdComponent into j2 from component in j2.DefaultIfEmpty()
    join product1 in _dbContext.Products on component.IdProduct equals product.IdProduct into j3 from product in j3.DefaultIfEmpty()
    join customer1 in _dbContext.Customers on custart.IdCustomer equals customer.Id into j4 from customer in j4.DefaultIfEmpty()
    where custart.IdCustomer == customerId
    group new { custart, component, product, customer } by substrate into g
    select new SubstrateExtended
    {
        IdSubstrate = substrate.IdSubstrate,
        SubstrateType = substrate.SubstrateType,
        SubstrateCreationDate = substrate.SubstrateCreationDate,
        SubstrateStatus = substrate.SubstrateStatus,
        SubstrateInvetoryQuantity = substrate.SubstrateInvetoryQuantity,
        RecordCopyDate = substrate.RecordCopyDate,
        MappedStatus = substrate.MappedStatus,
        ProductRef = string.Join(", ", g.Select(t => t.product.ProductRef).Distinct()),
        Acr = string.Join(", ", g.Select(t => t.customer.Accronym).Distinct())
    };

话虽如此,最好是重新考虑连接,并通过使用子查询进行预聚合来删除不同的和group by.

var substrates =
    from substrate in _dbContext.Substrates
    where custart.IdCustomer == customerId

    let acr = string.Join(", ",
        from custart in _dbContext.CustomerArticles
        join customer1 in _dbContext.Customers on custart.IdCustomer equals customer.Id
        where substrate.IdSubstrate == custart.ArticleId
        select customer.Accronym
    )

    let productRef = string.Join(", ",
        from component1 in _dbContext.ProductComponents
        join product1 in _dbContext.Products on component.IdProduct equals product.IdProduct
        where substrate.IdSubstrate == component.IdComponent
        select product.ProductRef
    )

    select new SubstrateExtended
    {
        IdSubstrate = substrate.IdSubstrate,
        SubstrateType = substrate.SubstrateType,
        SubstrateCreationDate = substrate.SubstrateCreationDate,
        SubstrateStatus = substrate.SubstrateStatus,
        SubstrateInvetoryQuantity = substrate.SubstrateInvetoryQuantity,
        RecordCopyDate = substrate.RecordCopyDate,
        MappedStatus = substrate.MappedStatus,
        ProductRef = productRef,
        Acr = acr
    };

Csharp相关问答推荐

Serilog SQL服务器接收器使用UTC作为时间戳

ASP.NET MVC购物车数量更新并从购物车中删除项目

如何使用C#和Graph API从Azure Directory获取用户详细信息

处理. netstandard2.0项目中HttpClient.SslProtocol的PlatformNotSupportedException问题""

. NET WireMock拒绝PostAsJsonAsync序列化

如何使用while循环实现异常处理

如果属性名为xyz,我需要使用System.Text.Json修改字符串类型的值""<>

如何使用新的Microsoft.IdentityModel.JsonWebToken创建JwtSecurityToken?

如何在实体框架中添加包含列表?

由于POST中的应用程序/JWT,出现不支持的内容类型异常

当索引和外键是不同的数据类型时,如何设置导航属性?

如何防止Visual Studio断点以红色突出显示到整行?

GODOT 4向C#中的字符串参数发送信号以等待

使用ASP.NET MVC for Lemon Squeezy X-Signature创建散列

C#中使用ReadOnlySpan的泛型类型推理

WPF:如何从DatagridHeader的内容模板绑定到词典项

C#定时器回调对象上下文?

这是T自身的布尔表达式是什么意思?

如何使用moq和xUnit对删除操作进行单元测试?

SendInput无法在C#中正确模拟键盘