我正在编写一个 C# .NET 5 应用程序,它将充当 Angular 前端的后端,提供 CRUD API。该应用程序的目的是管理飞行学校。
我正在编写 API 方法,它将返回飞行员列表和单个飞行员,即
https://myapp/api/pilots
和 https://myapp/api/pilots/{id}
。
我这里有三种方法:
GetPilots()
查看完整列表GetPilot(long idPilot)
了解详情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();
}
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();
}
_context.Pilot.tolist().Select(pilot => new PilotViewModel {Id = pilot.Id, Name = pilot.Name,FlightMinutes = pilot.Flights.Sum(flight => flight.Duration) });