【发布时间】:2022-01-14 09:54:32
【问题描述】:
我正在使用带有 EF 核心的 asp .net 核心 Web API。 我写了这个查询。但这需要 20-30 秒才能执行。
任何人都想改进这个查询。
var hotels = await _context.Hotels
.Where(i => (i.DestinationCode == request.Destination))
.Select(i => new HotelListHotelVm
{
Item1 = i.Item1,
Item2 = i.Item2,
Item3 = i.Item3,
Item4Code = i.Item4Code,
Item4Description = i.Item4.TypeDescription,
Item5 = i.Item5.Select(x => new HotelListHotelVm.HotelListItem5Vm
{
Code = x.Item5Code,
Description = x.Item5.Description,
}).Where(x =>(incomingItem5s.Length > 0 ) ? (incomingItem5s.Contains(x.Code)) : (x.Code != "")),
Item6 = i.Item6.Select(x => new HotelListHotelVm.HotelListHotelItem6Vm
{
Id = x.Id,
Item6TypeCode = x.Item6TypeCode,
Order = x.Order,
Path = x.Path,
VisualOrder = x.VisualOrder,
}).Take(3),
HotelFacilities = i.Facilities.ToList().Distinct().Take(6).Select(x => new HotelListHotelVm.HotelListFacilityVm {
Id = x.Id,
FacilityGroupCode = x.FacilityGroupCode,
HotelFacilityGroupDescription = x.FacilityGroup.Description,
FacilityCode = x.FacilityCode
}),
})
.Where( i => ((incomingItem4.Length > 0 ) ? (incomingItem4.Contains(i.Item4Code)) : (i.Item4Code != "")) )
.OrderByDescending(i => i.Code)
.PaginatedListAsync(request.PageNumber, request.PageSize);
foreach( var item in hotels.Items){
foreach(var facility in item.HotelFacilities){
foreach( var fac in _context.Facilities){
if(facility.FacilityCode == fac.Code){
facility.HotelFacilityDescription = fac.Description;
}
}
}
}
如果我删除那些 foreach 代码,查询需要 8-10 秒才能执行。
但我需要那些 foreach 代码。因为我需要HotelFacilityDescription
对优化查询有什么建议吗?
编辑i.Facilities - 模型
public class HotelFacility
{
// removed some
public int FacilityCode { get; set; }
public int FacilityGroupCode { get; set; }
public FacilityGroup FacilityGroup { get; set; }
public int HotelCode { get; set; }
public Hotel Hotel { get; set; }
}
}
【问题讨论】:
-
很遗憾我们使用的是 5.0 版
-
(1) 请在问题中包含
i.Facilities集合导航属性指向的模型类。 (2) 还要解释你想用.ToList().Distinct()实现什么,因为它没有做任何有用的事情 - Id 已经是唯一的,所以 distinct 运算符不会更改结果集,但可能会影响数据库中的查询性能查询优化器不够聪明,无法忽略它。 -
(1) 我已经更新了。 (2) 因为有一些重复的
FacilityCode -
(2) 您从模型中删除了一些可能必不可少的属性。查询显示必须有一个名为
Id的属性,它很可能是PK,即唯一,所以distinct 没有效果。不同的是使用 all 属性,而不仅仅是FacilityCode。这就是为什么我问您要实现什么目标 - 根据您的评论,它确实不会达到您的预期。 -
(1) 另外,你没有
public Facility Facility { get; set; }导航属性(就像你有FacilityGroup一样)?如果没有,为什么不呢?确保您拥有它,然后只需在 LINQ to Entities 查询中使用它,例如FacilityCode = x.FacilityCode, HotelFacilityDescription = x.Facility.Description并删除循环。
标签: entity-framework linq entity-framework-core query-optimization