我的Sql Sever数据库中有以下表格:
Tbl_Polygons: PolygonId, PolygonName
Tbl_PolygonPoints: 点名, Fk_PolygonId, 纬度, 经度 我正在使用以下方法来读取每个多边形,然后是它的点:
Using context = New myDbEntities()
Dim polygons = (From poly In context.Tbl_Polygons Select Poly).ToList()
polygons.ForEach(Sub(ply)
Dim polyPoint = (From pPoint In Tbl_PolygonPoints Where pPoint.Fk_PolygonId = ply.PolygonId
Select pPoint.Latitude, pPoint.Longitude).ToList()
polyPoint.ForEach(Sub(pPoint)
polygonPoints.Add(New PointLatLng(pPoint.Latitude, pPoint.Longitude))
End Sub)
DrawPolygon(ply,polygonPoints)
polygonPoints.Clear()
End Sub)
End Using
我桌上有大约20000个多边形。 上面提到的代码需要很长时间才能完全运行。 我试图压扁我的数据然后我可以删除我的内部ForEach循环。 SelectMany会解决我的问题吗?如果是,任何建议表示赞赏
非常感谢答案 0 :(得分:1)
这应该是一个评论,但它太长了。
包含与SelectMany具有相同的效果,您可以避免20.000个查询。在这两种情况下,您都需要具有导航属性的模型。如果使用Include,代码通常会更清晰 然后,第二个优化将是插入AsNoTracking以避免向上下文添加多个实体。在您的情况下,您可以首先使用数据库中的代码,以便从数据库开始编写模型。使用这个模型(抱歉c#,我可以阅读VB,但我不能写它)
[Table("Tbl_Polygons")]
class Polygon
{
[Key]
public int PolygonId {get; set;}
public string PolygonName {get; set;}
public virtual ICollection<Point> Points {get; set;}
}
[Table("Tbl_PolygonPoints")]
public Point
{
[Key]
public int PointId {get; set;}
public int Latitude {get; set;}
public int Lontitude {get; set;}
[ForeignKey("Fk_PolygonId")]
public virtual Polygon Polygon {get; set;}
public int Fk_PolygonId {get; set;}
}
你的代码就是这个。
var polygons = context.Polygons.Include(p => p.Points).AsNoTracking().ToList();
foreach (var polygon in polygons)
DrawPolygon(polygon, polygon.Points)
您可以使用SelectMany获得ef仅运行1个查询,但查询结果是具有多边形属性的点列表,因此在foreach中您需要检索相同多边形的点组(所以,在你的情况下,代码将不那么明确。)