我想对可能的一百万条记录进行更新.我喜欢Linq,我在下面写了这个,试图完成这个.我真的希望我写下这个可怕的错误.运行需要数小时和数小时.我用T-sql编写它,它在几分钟内运行.使用linq有更好的方法吗?
private static void UpdateZipCodes()
{
Console.WriteLine("Update Zip Codes Started");
DataDataContext _db = new DataDataContext();
var newBadZips = (from n in _db.NewCars
where n.loczip == null || n.loczip == ""
select n).ToList();
foreach (var bad in newBadZips)
{
string lZip = _db.Dealers.Where(x => x.DealerID == bad.DealerID).Select(x => x.Zipcode).SingleOrDefault();
bad.loczip = lZip;
_db.SubmitChanges();
}
Console.WriteLine("Update Zip Codes Finshed");
}
Run Code Online (Sandbox Code Playgroud)
T-Sql版本
UPDATE n
SET n.loczip = d.Zipcode
FROM NewCars AS n INNER JOIN
Dealers AS d ON n.DealerID = d.DealerID
where n.loczip is null or n.loczip = ''
Run Code Online (Sandbox Code Playgroud)
我理解linq做得更多的显而易见的事情.我想知道如何改进我的linq查询?
我并不是想要比较它们,我知道T-sql是实现这一目标的正确方法.这主要是因为我使用linq变得更好.我相信我会希望在某一点上以较小的比例做这样的事情,并希望在linq中正确地做到这一点.
您正在查询循环中每个项目的数据库.那很糟.这几乎总是错的,而且几乎总是很慢.
就像在T-SQL代码中所做的那样,在LINQ代码中使用Join来获取一个查询中所需的所有信息.
接下来,不要在每条记录之后更新数据库; 而是批量更新它们以减少网络流量.你不可能一次完成一百万,但你可以每100或1000或任何行提交一批(使用不同的批量大小的值来看看哪种方法效果最好).
此外,不要ToList在拥有一百万条记录的桌子上打电话.只需迭代查询,以便查询提供程序可以流式传输数据.
var newBadZips = (from car in _db.NewCars
where car.loczip == null || car.loczip == ""
join dealer in _db.Dealers
on car.DealerID equals dealer.DealerID
into dealers
select new{
car,
zip = dealers.Select(d => d.Zipcode)
.SingleOrDefault(),
});
int count = 0;
int batchSize = 1000;
foreach(var row in newBadZips)
{
row.car.loczip = row.zip;
if(++count % batchSize == 0)
_db.SubmitChanges();
}
Run Code Online (Sandbox Code Playgroud)