问题描述
我已经编写了一些非常不错的,时髦的库,供LinqToSql使用. (有一天我有时间考虑的话,我可能会将其开源... :))
I've written some really nice, funky libraries for use in LinqToSql. (Some day when I have time to think about it I might make it open source... :) )
无论如何,我不确定这是否与我的库有关,但是我发现,当我在一个事务中拥有大量已更改的对象,然后调用DataContext.GetChangeSet()
时,事情开始变得
Anyway, I'm not sure if this is related to my libraries or not, but I've discovered that when I have a large number of changed objects in one transaction, and then call DataContext.GetChangeSet()
, things start getting reaalllly slooowwwww. When I break into the code, I find that my program is spinning its wheels doing an awful lot of Equals()
comparisons between the objects in the change set. I can't guarantee this is true, but I suspect that if there are n objects in the change set, then the call to GetChangeSet()
is causing every object to be compared to every other object for equivalence, i.e. at best (n^2-n)/2 calls to Equals()
...
是的,我当然可以分别提交每个对象,但这有点违反了交易的目的.在我编写的程序中,我可以有一个批处理作业,其中包含100,000个单独的项目,所有这些项目都需要一起提交.大约有50亿次比较.
Yes, of course I could commit each object separately, but that kinda defeats the purpose of transactions. And in the program I'm writing, I could have a batch job containing 100,000 separate items, that all need to be committed together. Around 5 billion comparisons there.
所以问题是:(1)我对情况的评估正确吗?您是在纯教科书LinqToSql中获得这种行为的,还是我的库正在执行此操作? (2)是否有一个标准/合理的解决方法,这样我就可以创建批处理,而不会因更改集中的每个额外对象而使程序在几何上变慢了?
So the question is: (1) is my assessment of the situation correct? Do you get this behavior in pure, textbook LinqToSql, or is this something my libraries are doing? And (2) is there a standard/reasonable workaround so that I can create my batch without making the program geometrically slower with every extra object in the change set?
推荐答案
最后,我决定重写批处理,以便每个单独的项目都可以独立保存,而这一切都在一笔大交易中完成.换句话说,而不是:
In the end I decided to rewrite the batches so that each individual item is saved independently, all within one big transaction. In other words, instead of:
var b = new Batch { ... };
while (addNewItems) {
...
var i = new BatchItem { ... };
b.BatchItems.Add(i);
}
b.Insert(); // that's a function in my library that calls SubmitChanges()
..您必须执行以下操作:
.. you have to do something like this:
context.BeginTransaction(); // another one of my library functions
try {
var b = new Batch { ... };
b.Insert(); // save the batch record immediately
while (addNewItems) {
...
var i = new BatchItem { ... };
b.BatchItems.Add(i);
i.Insert(); // send the SQL on each iteration
}
context.CommitTransaction(); // and only commit the transaction when everything is done.
} catch {
context.RollbackTransaction();
throw;
}
您可以看到为什么第一个代码块更整洁,更自然地使用,但是很遗憾我被迫使用第二个结构...
You can see why the first code block is just cleaner and more natural to use, and it's a pity I got forced into using the second structure...
这篇关于如何避免大型Linq交易的几何速度放慢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!