【问题标题】:Entity Framework Core - LINQ select over navigational properties creates invalid queryEntity Framework Core - LINQ 选择导航属性会创建无效查询
【发布时间】:2016-06-05 05:40:00
【问题描述】:

目前,我正在开发一个 Asp.Net Core 网站,并使用 Entity Framework Core(目前为 RC1)在开发机器上通过 SQL Express LocalDB 访问数据库,尽管测试服务器上的 MS SQL 给出了相同的错误。

我遇到了一个问题,即在查询多级导航属性时,会生成无效的 SQL。我创建了以下测试代码来重现该问题:

4个代表数据库表的类

public class CarManufacturer
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public List<CarModel> CarModels { get; set; }
}

public class CarModel
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public Guid CarManufacturerId { get; set; }
    public CarManufacturer CarManufacturer { get; set; }
    public List<CarTestDriver> CarTestDrivers { get; set; }
}

public class CarTestDriver
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public Guid CarModelId { get; set; }
    public CarModel CarModel { get; set; }
    public List<SpeedingTicket> SpeedingTickets { get; set; }
}

public class SpeedingTicket
{
    public Guid Id { get; set; }
    public decimal Amount { get; set; }
    public Guid CarTestDriverId { get; set; }
    public CarTestDriver CarTestDriver { get; set; }
}

Context 类中的 DbSets

    public DbSet<CarManufacturer> CarManufacturers { get; set; }
    public DbSet<CarModel> CarModels { get; set; }
    public DbSet<CarTestDriver> CarTestDrivers { get; set; }
    public DbSet<SpeedingTicket> SpeedingTickets { get; set; }

现在我创建一个 linq 查询来给我按制造商排序的票的总数

        var ticketCostByManufacturers = Context.CarManufacturers
            .Select(manufacturer => new
            {
                manufacturer.Name,
                TotalTicketAmount = manufacturer.CarModels.SelectMany(model => model.CarTestDrivers).SelectMany(driver => driver.SpeedingTickets).Sum(ticket => ticket.Amount)
            })
            .ToList();

它做了两件事:

  1. 创建一个查询来检索所有制造商 ID 和名称
  2. 使用以下无效 SQL 查询所有票证: (仅当第一个查询确实产生结果时)

    SELECT [model].[Id],
    [model].[Amount],
    [model].[CarTestDriverId],
    [model].[CarManufacturerId], -- Invalid Column
    [model].[Id],
    [driver].[Id],
    [ticket].[Amount]
    FROM [SpeedingTicket] AS [model]
    CROSS JOIN [CarTestDriver] AS [driver]
    CROSS JOIN [SpeedingTicket] AS [ticket]      
    

由于实体SpeedingTicket 的表上的列名CarManufacturerId 无效,查询导致异常,因为查询确实选择了[SpeedingTicket] AS [model]

我已经尝试过.Include() 以及 Fluent API,但两者都没有让我找到如何在此处正确使用 Entity Framework Core 来执行查询的解决方案。

异常消息本身表明我的模型和数据库不同步,我应该创建一个新的迁移,但实际上它们是同步的。我猜这个建议来自 EF,它假设在找不到列时数据库架构不匹配。

编辑澄清:

问题的目的是查明这是否是我的设置中的错误(例如缺少 Fluent API 的配置),或者它是否仍然是当前版本的 Entity Framework Core 中的错误。 @Ivan Stoev 确实指出它是后者,是实体框架当前代码中的一个错误。

【问题讨论】:

  • 问题是……?其实没关系。您的 LINQ 查询是正确的,因此显然问题出在 EF7 中。它还没有发布,所以有bug是正常的,你最好不要浪费时间使用(测试)非生产代码。
  • 你确实回答了我的问题。我想知道我这边是否有错误,或者是否与实体框架的当前状态有关。

标签: c# sql linq entity-framework-core


【解决方案1】:

据我了解,实体框架代码没有问题。Output of entity framework code。 但是这里提到的Sql查询[model]是实体框架创建的[SpeedingTickets]表。该表不包含任何列调用 [CarManufacturerId]。这是错误。

【讨论】:

  • 感谢您的回答,这也表明查询从 LINQ 转换为 SQL 的方式存在错误。但是,我宁愿接受一个答案,该答案提供了有关查询究竟为什么错误(以及可能的解决方法)的更多详细信息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-20
  • 2014-02-18
  • 2017-01-01
  • 2023-03-17
  • 1970-01-01
  • 2021-05-17
  • 1970-01-01
相关资源
最近更新 更多