Entity Framework Core 将列映射到对象

Entity Framework Core mapping columns to object

提问人:Răzvan Puștea 提问时间:10/11/2023 最后编辑:marc_sRăzvan Puștea 更新时间:10/11/2023 访问量:88

问:

我有一个表示查询的字符串。查询非常复杂,涉及多个联接。这是我选择的:

SELECT 
    [SO].Id, [SO].SerialNumber, [SO].EstimateId,
    CASE
        WHEN [SO].EstimateId IS NOT NULL 
            THEN (SELECT TOP(1) [EST].[SerialNumber]
                  FROM [Estimates] AS [EST]
                  WHERE ([EST].[OrganizationId] = 1) 
                    AND ([EST].[EstimateId] = [SO].[EstimateId]))
            ELSE NULL
    END, 
    [SO].RecCreateTs, [SO].EstimatedDeliveryDate, [SO].Status, 
    [SO].PriceTotal, [SO].InRevision, [CST].CompanyName, 
    [CON].FirstName, [CON].LastName, [SOR].FirstName, [SOR].LastName, 
    [SOR].EstimatedDeliveryDate, [SOR].PriceTotal

有些列是相同的,但它们来自不同的表。

我试图映射 Select 中的属性:

var salesOrders = _context.SalesOrders.FromSqlRaw(sqlString)
    .Select(so => new SalesOrder
    {
        Id = so.Id,
        SerialNumber = so.SerialNumber,
        EstimateId = so.EstimateId,
        // the property below is [NotMapped]
        EstimateSerialNumber = so.EstimateId != null ? _context.Estimates.AsNoTracking().FirstOrDefault(w => w.OrganizationId == organizationId && w.EstimateId == so.EstimateId).SerialNumber : null,
        RecCreateTs = so.RecCreateTs,
        EstimatedDeliveryDate = so.EstimatedDeliveryDate,
        Status = so.Status,
        PriceTotal = so.PriceTotal,
        InRevision = so.InRevision,
        Customer = new Customer { CompanyName = so.Customer.CompanyName },
        CustomerContact = new CustomerContact { FirstName = so.CustomerContact.FirstName, LastName = so.CustomerContact.LastName },
        SalesOrderRevisions = so.InRevision
        ? new List<SalesOrderRevision>
        {
            so.SalesOrderRevisions.OrderByDescending(x => x.Id).Select(soRevision => new SalesOrderRevision
            {
                CustomerContact = new CustomerContact { FirstName = soRevision.CustomerContact.FirstName, LastName = soRevision.CustomerContact.LastName },
                EstimatedDeliveryDate = soRevision.EstimatedDeliveryDate,
                PriceTotal = soRevision.PriceTotal
            }).FirstOrDefault()
        }
        : null
    })
    .ToList();

但它没有用。如何告诉 EF Core 如何将每一列与相应的对象属性相关联?

C# LINQ 实体框架核心 EF-Core-3.1

评论

0赞 Dai 10/11/2023
您使用的究竟是哪个版本的 EF 或 EF Core?
0赞 Răzvan Puștea 10/11/2023
我正在使用 EF Core 3.1
0赞 Dai 10/11/2023
是否有原因无法更新到 EF Core 7?EF Core 3.1 仍然非常有限,并且缺少许多功能(与最近才添加到 EF Core 7 的旧非 Core EF 6.4 相比)。
0赞 user16606026 10/11/2023
什么不起作用?是否有任何异常或结果不符合您的期望?
0赞 Răzvan Puștea 10/11/2023
Microsoft.Data.SqlClient.SqlException:“未为”s“的第 4 列指定列名。为“s”多次指定了“FirstName”列。列名称“CustomerId”无效。列名称“CustomerContactId”无效。

答:

0赞 user16606026 10/11/2023 #1

原始 SQL 查询存在一些问题,例如:

...[CON].FirstName, [CON].LastName, [SOR].FirstName, [SOR].LastName...

这会导致 2 和 2 ,这会使 EF 感到困惑,因为它不知道您映射到哪个 。FirstNameLastNameFirstNameSalesOrder

我建议根本不使用,而是使用适当的 LINQ 来操作查询。我们不知道 or or or 是什么,因此可能无法提供进一步的帮助。但请先尝试自己重写 LINQ 查询。.FromSqlRaw(sqlString)SORCONSOCST

评论

0赞 Răzvan Puștea 10/11/2023
我之所以选择这种方法,是因为我在 OrderBy 子句中使用了 LastIndexOf(),而 EF 无法将其转换为 SQL 查询。
0赞 user16606026 10/11/2023
根据用途,可以先将查询结果存储在内存中,然后在本地执行 OrderBy。OrderBy()
0赞 Răzvan Puștea 10/11/2023
我需要订购,这样我之后只能接受 25 条排序记录。加载到内存中意味着加载数千条记录。
0赞 user16606026 10/11/2023
下次也请在问题中涉及这些条件。对于此类情况,可以查看 EF 是否提供了有帮助的功能
0赞 Răzvan Puștea 10/11/2023
对不起,没有提及条件。EntityFunctions 类仅在 .NET 4 中可用。我使用 .NET 3.1