我正在研究實用程序來讀取我已經給出的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(...'行?仍然很慢? –