我正在研究实用程序来读取我已经给出的JSON文件并将其转换为SQL Server。我选择的武器是一个.NET Core控制台应用程序(我试图用.NET Core来完成我所有的新工作,除非有令人信服的理由)。我把所有的东西都“工作”了,但是在某个地方显然存在问题,因为这些表现真的很可怕,几乎无法使用。JSON数组到实体框架核心非常慢?
JSON文件大约为27MB,包含214个元素的主数组,每个数组都包含两个字段以及150-350条记录的数组(该数组有几个字段并可能包含一个小的< 5条记录数组或两个)。总记录大约是35,000。
在下面的代码中,我更改了一些名称并删除了一些字段以使其更具可读性,但所有实际工作的逻辑和代码都没有改变。
请记住,我已经做了大量的测试,调用SaveChanges()的位置和次数,最初认为Db的次数是问题。尽管下面的版本在214-记录循环的每次迭代中调用SaveChanges()一次,但我试着将它移到整个循环结构之外,并且没有明显的性能变化。换句话说,在Db为零的情况下,这仍然很慢。你问的速度有多慢,24小时运行如何击中你?我愿意在这一点上尝试任何东西,我甚至考虑将整个过程转移到SQL Server中,但是在C#中工作比在TSQL中工作得多。
static void Main(string[] args)
{
string statusMsg = String.Empty;
JArray sets = JArray.Parse(File.ReadAllText(@"C:\Users\Public\Downloads\ImportFile.json"));
try
{
using (var _db = new WidgetDb())
{
for (int s = 0; s < sets.Count; s++)
{
Console.WriteLine($"{s.ToString()}: {sets[s]["name"]}");
// First we create the Set
Set eSet = new Set()
{
SetCode = (string)sets[s]["code"],
SetName = (string)sets[s]["name"],
Type = (string)sets[s]["type"],
Block = (string)sets[s]["block"] ?? ""
};
_db.Entry(eSet).State = Microsoft.EntityFrameworkCore.EntityState.Added;
JArray widgets = sets[s]["widgets"].ToObject<JArray>();
for (int c = 0; c < widgets.Count; c++)
{
Widget eWidget = new Widget()
{
WidgetId = (string)widgets[c]["id"],
Layout = (string)widgets[c]["layout"] ?? "",
WidgetName = (string)widgets[c]["name"],
WidgetNames = "",
ReleaseDate = releaseDate,
SetCode = (string)sets[s]["code"]
};
// WidgetColors
if (widgets[c]["colors"] != null)
{
JArray widgetColors = widgets[c]["colors"].ToObject<JArray>();
for (int cc = 0; cc < widgetColors.Count; cc++)
{
WidgetColor eWidgetColor = new WidgetColor()
{
WidgetId = eWidget.WidgetId,
Color = (string)widgets[c]["colors"][cc]
};
_db.Entry(eWidgetColor).State = Microsoft.EntityFrameworkCore.EntityState.Added;
}
}
// WidgetTypes
if (widgets[c]["types"] != null)
{
JArray widgetTypes = widgets[c]["types"].ToObject<JArray>();
for (int ct = 0; ct < widgetTypes.Count; ct++)
{
WidgetType eWidgetType = new WidgetType()
{
WidgetId = eWidget.WidgetId,
Type = (string)widgets[c]["types"][ct]
};
_db.Entry(eWidgetType).State = Microsoft.EntityFrameworkCore.EntityState.Added;
}
}
// WidgetVariations
if (widgets[c]["variations"] != null)
{
JArray widgetVariations = widgets[c]["variations"].ToObject<JArray>();
for (int cv = 0; cv < widgetVariations.Count; cv++)
{
WidgetVariation eWidgetVariation = new WidgetVariation()
{
WidgetId = eWidget.WidgetId,
Variation = (string)widgets[c]["variations"][cv]
};
_db.Entry(eWidgetVariation).State = Microsoft.EntityFrameworkCore.EntityState.Added;
}
}
}
_db.SaveChanges();
}
}
statusMsg = "Import Complete";
}
catch (Exception ex)
{
statusMsg = ex.Message + " (" + ex.InnerException + ")";
}
Console.WriteLine(statusMsg);
Console.ReadKey();
}
LINQ的-2-SQL是另一种选择。问题可能是它在后端对数据库进行单独插入。你打开EntityFramework的日志记录功能吗?只需连线到'Console.Out' –
哪一行是最慢的?你是否试图用调试器来发现它? –
你说甚至没有调用'SaveChanges'也很慢?如何评论所有'_db.Entry(...'行?仍然很慢? –