我正在将ASP.NET Core 2.1.1和EF Core 2.1.4一起使用。
在我的应用程序数据库中,我确实有部件,并且每个部件在ClusterPart上都具有属性:参考。
我的集群部件可以具有直接引用,例如“ B-> C ”,也可以具有两步引用,例如“ A-> B-> C ”。
我想将此参考逻辑封装到一个返回IQueryable的服务调用中,以便可以在多个位置使用此IQueryable添加更多信息。
用于将引用的ClusterParts返回为IQueryable的服务。不要在linq语句上花费太多时间:
public IQueryable<ClusterPart> GetReferencedClusterParts(long partId)
{
// Requested ClusterPart
var requestedClusterPart = _clusterPartDao.GetClusterPartsByPartId(partId)
.Include(cp => cp.Part)
.ThenInclude(p => p.Supplier)
.ThenInclude(s => s.SupplierType)
.FirstOrDefault();
// Get direct references B to C
var resultB2C = _clusterPartDao.GetAll() // This is just _context.Table
.Where(cpB => cpB.PartId.Equals(requestedClusterPart.PartId)) // Requested PartId
.SelectMany(cpB => cpB.ReferenceClusterPartIdFromNavigations) // Reference from A/B to C
.Select(rB2C => rB2C.ClusterPartIdToNavigation) // C ClusterPart
.Where(cpC => cpC.Part.Supplier.SupplierTypeId.Equals(1)) // SupplierType C
// Add 2 step references A to B to C
var resultA2B2C = _clusterPartDao.GetAll() // This is just _context.Table
.Where(cpA => cpA.PartId.Equals(requestedClusterPart.PartId)) // Requested PartId
.SelectMany(cpA => cpA.ReferenceClusterPartIdFromNavigations) // Reference from A to B
.Select(rA2B => rA2B.ClusterPartIdToNavigation) // B ClusterPart
.SelectMany(cpB => cpB.ReferenceClusterPartIdFromNavigations) // Reference from B to C
.Select(rB2C => rB2C.ClusterPartIdToNavigation) // B ClusterPart
.Where(cpC => cpC.Part.Supplier.SupplierTypeId.Equals(1)); // SupplierType C
return resultA2B2C.Union(resultB2C);
}
基本上,我只是选择引用为“ B-> C ”和“ A-> B-> C ”之类的“ C” ClusterParts。
此方法供以下人员使用:
var resultCP = GetReferencedClusterParts(12345)
.Select(cpC => new ElementDTO
{
PartId = cpC.PartId,
PartName = cpC.Part.Name
});
result.References = resultCP.ToList();
我一点击resultCP.ToList(),查询就会被触发。 由于LINQ决定选择包含1000万行的完整表“ Part”,因此花费的时间非常长,如果调用“ GetReferencedClusterParts”仅返回约10个结果。我在SQL Server Profiler中证实了这一点。
当我删除“ cpC.Part.Name”时,“ Part”表未完全选中。
我如何影响这种情况?我想避免EF Core或LINQ决定选择整个大表,而不是只将很少的信息加入到IQueryable中,这很快,但是我不知道为什么完全选择了表“ Part”。