EF6 级联对象的设置速度非常慢
Posted
技术标签:
【中文标题】EF6 级联对象的设置速度非常慢【英文标题】:EF6 cascade object very slow to setup 【发布时间】:2016-03-09 14:58:43 【问题描述】:我在尝试检索数据时遇到了实体框架问题。 我将工作分为多个步骤:
-
生成查询
执行它并从数据库中检索数据集。
使用数据集填写我的 ViewModel。
实际上,第 1 步和第 2 步非常快,第 3 步最多可能需要 1 分钟(对于 200 条记录)。这意味着它与 SQL 无关(我将查询从调试器复制到 MSSMS,并且它在不到一秒的时间内执行)。
首先,我使用步骤 3B,为简单起见,我检索了一个 Job
实体,我将其转换为一个 MapMarker
对象。我认为是ConvertAll
减慢了进程。
在阅读了一些 SO 之后,我使用 Select 进行了测试,但结果是一样的。
唯一的一点是,如果我使用“主要对象”,在这个例子中:工作,一切都很快;作为测试,我将 Job.Job_ID 放入 all 字段,执行时间正常(不到一秒)。
然后我再次插入这个:,Latitude = _Job.Maintenance.Equipement.Location.GPS.GPS_Latitude.Value
,慢慢地又回来了。
我什至使用 foreach 循环尝试了第 3C 步(我知道这不是更好,但还可以......),但它和其他解决方案一样慢。
主要问题是: 我在 EF6 配置(或其他地方?)中缺少什么使这个过程如此缓慢?
我将用旧的方式执行我自己的 sql 查询,我开始使用 EF,我想这些实体应该是可用的,现在使用“简单”对象工作得很好,但如果你不能级联它们..附加值是多少?
下面是我所说的步骤。
第 1 步:
IEnumerable<Job> Jobs = db.Job.Include(e => e.Maintenance.MaintenancePlan.MaintenanceType).Include(e => e.Maintenance.MaintenancePlan.MaintenanceType)
.Include(e => e.Maintenance.MaintenancePlan.MaintenanceType.Shape)
.Include(e => e.Maintenance.MaintenanceStatus)
.Include(e => e.Users)
.Include(e => e.Users.Color)
.Include(e => e.Maintenance.Equipement.Location.GPS);
第 2 步:
List<Job> listJobs = Jobs.ToList();
步骤 3A:
IEnumerable<MapMarker> IEMarkerJobsA = Jobs.AsEnumerable().Select(_Job => new MapMarker
ID = string.Format("Job_0", _Job.Job_ID)
,Latitude = _Job.Maintenance.Equipement.Location.GPS.GPS_Latitude.Value
,Longitude = _Job.Maintenance.Equipement.Location.GPS.GPS_Longitude.Value
);
List<MapMarker> listMarkerJobsA = IEMarkerJobsA.ToList();
步骤 3B:
IEnumerable listMarkerJobs = listJobs.ConvertAll( 新转换器(MapMarker.MapMarkerFactory)); 当工厂是这样的:
public static MapMarker MapMarkerFactory(Job _Job)
MapMarker A = new MapMarker();
A.ID = String.Format("Job_0", _Job.Job_ID);
A.Latitude = _Job.Maintenance.Equipement.Location.GPS.GPS_Latitude.Value;
A.Longitude = _Job.Maintenance.Equipement.Location.GPS.GPS_Longitude.Value;
A.Title = String.Format("1", (_Job.Users != null) ? String.Format("[0]", _Job.Users.Users_NickName) : "", _Job.Maintenance.Equipement.Equipement_Name);
A.Icon = GetIconePath((_Job.Users != null) ? _Job.Users.Color.Color_Name : "red", _Job.Maintenance.MaintenancePlan.MaintenanceType.Shape.Shape_Name, _Job.Maintenance.MaintenanceStatus.MaintenanceStatus_Description, "13px");
A.IconSize = new Size(13, 13);
A.WindowInfoContent = String.Format("JobID= 0", _Job.Job_ID);
return A;
步骤 3C:
List<MapMarker> listMarkerJobs = new List<MapMarker>();
foreach (Job _Job in Jobs)
MapMarker A = new MapMarker();
A.ID = String.Format("Job_0", _Job.Job_ID);
A.Latitude = _Job.Maintenance.Equipement.Location.GPS.GPS_Latitude.Value:
A.Longitude = _Job.Maintenance.Equipement.Location.GPS.GPS_Longitude.Value;
A.Title = String.Format("1", (_Job.Users != null) ? String.Format("[0]", _Job.Users.Users_NickName) : "", _Job.Maintenance.Equipement.Equipement_Name);
A.Icon = MapMarker.GetIconePath((_Job.Users != null) ? _Job.Users.Color.Color_Name : "red", _Job.Maintenance.MaintenancePlan.MaintenanceType.Shape.Shape_Name, _Job.Maintenance.MaintenanceStatus.MaintenanceStatus_Description, "13px");
A.IconSize = new System.Drawing.Size(13, 13);
A.WindowInfoContent = String.Format("JobID= 0", _Job.Job_ID);
listMarkerJobs.Add(A);
【问题讨论】:
我相信您的代码中存在 N+1 问题,请尝试分析 EF 生成的 SQL 查询,看看您是否忘记在查询中包含某些表。 【参考方案1】:在第 3 部分试试这个
List<MapMarker> listMarkerJobs = Jobs.AsNoTracking().Select(_Job => new MapMarker
ID = string.Format("Job_0", _Job.Job_ID),
Latitude = _Job.Maintenance.Equipement.Location.GPS.GPS_Latitude.Value,
Longitude = _Job.Maintenance.Equipement.Location.GPS.GPS_Longitude.Value
).ToList();
【讨论】:
以上是关于EF6 级联对象的设置速度非常慢的主要内容,如果未能解决你的问题,请参考以下文章