如何避免“System.InvalidOperationException:客户端投影包含对常量表达式的引用”错误?

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

我正在编写一个 C# .NET 5 应用程序,它将充当 Angular 前端的后端,提供 CRUD API。该应用程序的目的是管理飞行学校。

我正在编写 API 方法,它将返回飞行员列表和单个飞行员,即

https://myapp/api/pilots
https://myapp/api/pilots/{id}

我这里有三种方法:

  1. GetPilots()
    查看完整列表
  2. GetPilot(long idPilot)
    了解详情
  3. 辅助方法
    GetFlightTime(long idPilot)
    返回每个飞行员的总飞行时间,计算飞行时间的总和。

我的问题:详细方法有效,因为我首先调用辅助函数,然后然后我在返回的视图模型中使用结果。但是

GetPilots()
不起作用并返回错误
System.InvalidOperationException: The client projection contains a reference to a constant expression of 'QTBWeb.Models.PilotsRepository' through the instance method 'GetFlightTime'. This could potentially cause a memory leak; consider making the method static so that it does not capture constant in the instance.

这是因为我在 LINQ 表达式中调用

GetFlightTime
方法吗?我不明白“使方法静态”建议。如何重新格式化代码以使其正常工作? 谢谢!

public IEnumerable<PilotViewModel> GetPilots() // THIS METHOD RETURNS ERROR { return _context.Pilots .Select(pilot => new PilotViewModel { Id = pilot.Id, Name = pilot.Name, FlightMinutes = GetFlightTime(pilot.Id) // THE PROBLEM IS HERE }) .ToList(); } public PilotViewModel GetPilot(long idPilot) // THIS METHOD WORKS { var _flightMinutes = GetFlightTime(idPilot); return _context.Pilots .Select(pilot => new PilotViewModel { Id = pilot.Id, Name = pilot.Name, FlightMinutes = _flightMinutes }) .Where(pilot => pilot.Id == idPilot) .FirstOrDefault(); } public int GetFlightTime(long idPilot) { return _context.Flights .Where(flight => flight.pilot == idPilot) .Select(flight => flight.Duration).Sum(); }


c# rest linq
2个回答
4
投票
Pilot

类具有

Flights
的集合,作为您拥有的
Flight.Pilot
一对多映射的另一侧。 然后,您可以使用此集合来计算总和,而无需在数据库中查询
Pilot
的每个循环实例。
你的代码看起来像这样:

public IEnumerable<PilotViewModel> GetPilots() { return _context.Pilots .Include(pilot => pilot.Flights) // Include Flights to join data .Select(pilot => new PilotViewModel { Id = pilot.Id, Name = pilot.Name, FlightMinutes = pilot.Flights.Sum(flight => flight.Duration) }); } public PilotViewModel GetPilot(long idPilot) { return _context.Pilots .Include(pilot => pilot.Flights) // Include Flights to join data .Where(pilot => pilot.Id == idPilot) // Notice how we filter first .Select(pilot => new PilotViewModel { Id = pilot.Id, Name = pilot.Name, FlightMinutes = pilot.Flights.Sum(flight => flight.Duration) }) .FirstOrDefault(); }



0
投票
_context.Pilot.tolist().Select(pilot => new PilotViewModel {Id = pilot.Id, Name = pilot.Name,FlightMinutes = pilot.Flights.Sum(flight => flight.Duration) });

    

© www.soinside.com 2019 - 2024. All rights reserved.