我想在ASP.NET MVC中使用Linq将大约100万条记录插入到数据库中。但是,当我尝试以下代码时,它不起作用。它正在抛出一个OutOfMemoryException
。而且它在循环中花了3天。有人可以帮我这个吗?
db.Database.ExecuteSqlCommand("DELETE From [HotelServices]");
DataTable tblRepeatService = new DataTable();
tblRepeatService.Columns.Add("HotelCode",typeof(System.String));
tblRepeatService.Columns.Add("Service",typeof(System.String));
tblRepeatService.Columns.Add("Category",typeof(System.String));
foreach (DataRow row in xmltable.Rows)
{
string[] servicesarr = Regex.Split(row["PAmenities"].ToString(), ";");
for (int a = 0; a < servicesarr.Length; a++)
{
tblRepeatService.Rows.Add(row["HotelCode"].ToString(), servicesarr[a], "PA");
}
String[] servicesarrA = Regex.Split(row["RAmenities"].ToString(), ";");
for (int b = 0; b < servicesarrA.Length; b++)
{
tblRepeatService.Rows.Add(row["hotelcode"].ToString(), servicesarrA[b], "RA");
}
}
HotelAmenties _hotelamenties;
foreach (DataRow hadr in tblRepeatService.Rows)
{
_hotelamenties = new HotelAmenties();
_hotelamenties.Id = Guid.NewGuid();
_hotelamenties.ServiceName = hadr["Service"].ToString();
_hotelamenties.HotelCode = hadr["HotelCode"].ToString();
db.HotelAmenties.Add(_hotelamenties);
}
db.SaveChanges();
tblRepeatService
表有大约100万行。
答案 0 :(得分:2)
像这样的批量插入在LINQtoSQL中非常低效。每个插入都会创建至少三个对象(DataRow
,HotelAmenities
对象及其跟踪记录),从而为您不需要的对象留下记忆。
鉴于您已经有DataTable
,您可以使用System.Data.SqlClient.SqlBulkCopy
将表的内容推送到SQL服务器上的临时表,然后使用单个insert
语句将数据加载到其最终目标。这是迄今为止我发现的将数千条记录从内存移动到SQL的最快方法。
答案 1 :(得分:1)
如果表现无关紧要,这是一次性的工作,你可以坚持你的使用方式。你的问题是你最后只保存,所以实体框架必须同时存储和生成100万个操作的SQL,修改你的代码,这样你就可以保存每1000个左右的插入而不仅仅是在结尾,它应该工作得很好。
int i = 0;
foreach (DataRow hadr in tblRepeatService.Rows)
{
_hotelamenties = new HotelAmenties();
_hotelamenties.Id = Guid.NewGuid();
_hotelamenties.ServiceName = hadr["Service"].ToString();
_hotelamenties.HotelCode = hadr["HotelCode"].ToString();
db.HotelAmenties.Add(_hotelamenties);
if((i%1000)==0){
db.SaveChanges();
}
i++;
}
db.SaveChanges();