我有一个看似常见的问题,但我无法想出如何实现所需的结果。我有一个嵌套的实体,其中定义了导航属性,如下图所示。
对于给定的MapLine,地图点集合可能非常大,而且对于一个MapLayer,可能有大量的MapLines。
这里的问题是,使用Entity Framework将MapLayer对象插入到数据库中的最佳方法,并仍然保持由导航属性定义的关系?
标准的Entity Framework实现。
dbContext.MapLayers.Add(mapLayer);
dbContext.SaveChanges();
这会导致内存急剧增长和返回时间较差。
我尝试过实现EntityFramework.BulkInsert包, 但它不符合对象之间的关系。
这似乎是一个问题,有人以前遇到过,但我似乎找不到任何解释如何完成此任务的资源。
更新
我尝试了Richard提供的建议,但我不明白如何处理像我描述的嵌套实体这样的实体。 我假定需要插入MapLayer对象,然后是MapLines,然后是MapPoints,以遵守数据库中的PF / FK关系。 我目前正在尝试以下代码,但这似乎是不正确的。
dbContext.MapLayers.Add(mapLayer);
dbContext.SaveChanges();
List<MapLine> mapLines = new List<MapLine>();
List<MapPoint> mapPoints = new List<MapPoint>();
foreach (MapLine mapLine in mapLayer.MapLines)
{
//Update the mapPoints.MapLine properties to reflect the current line object
var updatedLines = mapLine.MapPoints.Select(x => { x.MapLine = mapLine; return x; }).ToList();
mapLines.AddRange(updatedLines);
}
using (TransactionScope scope = new TransactionScope())
{
MyDbContext context = null;
try
{
context = new MyDbContext();
context.Configuration.AutoDetectChangesEnabled = false;
int count = 0;
foreach (var entityToInsert in mapLines)
{
++count;
context = AddToContext(context, entityToInsert, count, 100, true);
}
context.SaveChanges();
}
finally
{
if (context != null)
context.Dispose();
}
scope.Complete();
}
更新2
尝试了多种方法后,我最终放弃了,并将MapLayer作为实体插入,并将MapLines => MapPoints关系存储为原始的Json字符串,存储在MapLayer实体的字节数组中(因为我不针对这些结构进行查询,所以对我来说这很有效)。
俗话说得好,“它并不美观,但它有效”。
我确实成功地使用BulkInsert包管理了EF之外的关系,但是当我尝试使用EF将数据重新引入系统时,又遇到了内存问题。目前看来,EF无法高效地处理大型数据集和复杂关系。