【发布时间】:2019-05-08 12:19:48
【问题描述】:
早上好。
今天我遇到了 EF 6 和 AddRange 方法的问题。有一个 WPF 应用程序可以处理约 100000 条记录。我写了导入功能,从.csv文件中导入数据,出现了问题。
看起来像这样:
private void FileImport()
{
//Open dialog to choose file
OpenFileDialog ofd = new OpenFileDialog();
string fileName = string.Empty;
if (ofd.ShowDialog() == true)
{
fileName = ofd.FileName;
}
if (!string.IsNullOrEmpty(fileName))
{
//getting all lines
var lines = File.ReadAllLines(fileName).ToList();
//File requirements says that there cannot be empty values in first element
if (lines.Any(line => line.Split(';')[0].Equals("null")))
{
MessageBox.Show("BLA BLA BLA");
}
else
{
List<List<string>> splitLines = new List<List<string>>();
//split lines into smaller list. For every sublist in list we will do things separatly in separate threads to get it faster.
for (int i = 0; i < lines.Count; i += 1000)
{
splitLines.Add(lines.GetRange(i, Math.Min(1000, lines.Count - i)));
}
var taskList = new List<Task>();
List<ut_katabcdx_file_filters> filterList = new List<ut_katabcdx_file_filters>();
foreach (var list in splitLines)
{
//define a Task
var t = new Task(() =>
{
foreach (var line in list)
{
var filters = line.Split(';');
//split line into elements array. It must have 6 elemets
if (filters.Count() == 6)
{
//Temporary declaration for parsing. If element that pretends to be decimals are empty we set its value to -100000.
decimal temp;
int tempi;
decimal? proga = filters[1].Equals("") ? -100000 : (decimal.TryParse(filters[1], out temp) ? (decimal?)temp : null);
decimal? progb = filters[2].Equals("") ? -100000 : (decimal.TryParse(filters[2], out temp) ? (decimal?)temp : null);
int? plan_sprz_rok = filters[3].Equals("") ? -100000 : (int.TryParse(filters[3], out tempi) ? (int?)tempi : null);
ut_katabcdx_file_filters filter = new ut_katabcdx_file_filters()
{
indeks = filters[0],
//produkty_iz = ProduktyIzChecked ? (filters[1].Equals("null") ? null : filters[1]) : string.Empty,
proga = ProgaChecked ? proga : -100000,
progb = ProgbChecked ? progb : -100000,
plan_sprz_rok = PlanSprzRokChecked ? plan_sprz_rok : -100000,
kat_tech = KatTechChecked ? (filters[4].Equals("null") ? null : filters[4]) : string.Empty,
kat_handl = KatHandlChecked ? (filters[5].Equals("null") ? null : filters[5]) : string.Empty,
};
filterList.Add(filter);
}
}
});
taskList.Add(t);
t.Start();
}
//wait for all tasks to end
Task.WaitAll(taskList.ToArray());
using (var ctx = new ABCDXContext())
{
ctx.ut_katabcdx_file_filters.AddRange(filterList);
ctx.SaveChanges();
string param_xml = GetParamXml();
Products = new ObservableCollection<ut_katabcdx_wytwor>(ctx.WytworFileUpdate(param_xml));
}
}
}
}
当我调试代码时,它会在ctx.ut_katabcdx_file_filters.AddRange(filterList); 处停止,并且不会更进一步。我检查了filterList.Count,大约有 60000 行。我也检查了数据库表,但它是空的。
是因为数据量大还是我做的不对? 如果有任何建议,我将非常感激。
【问题讨论】:
-
当你说它“不会走得更远”时,你需要等到它完成后才能看到数据库中的任何内容。插入 60k 条记录并不是一项快速的任务,尤其是对于 EF。您可能想查看其他用于批量插入数据的工具,
-
@DavidG 能坚持20分钟吗?
-
可能需要几个小时,这取决于很多因素。
-
简短回答 - 不要为此使用 EF。更长的答案 - 阅读stackoverflow.com/questions/13722014/…(这应该从> 20分钟到stackoverflow.com/questions/5940225/… 也值得一读。
-
当像这样插入大量行时,使用 SQL 批量复制的性能要高得多。有几个 Nuget 包为 Entity Framework 6 添加了批量插入支持。
标签: c# wpf entity-framework