它已经一段时间,因为这个问题问,但我最近碰到了一个类似类型的问题,并最终做低于这个帮助我们满足性能标准。
你基本上分割你的名单分成块,并在一个多线程的方式sperate线程中处理它们。每个新线程都会启动自己的uow,这需要您的实体被连接。
有一点要注意的是你的数据库需要进行快照隔离被启用。否则可能会导致死锁。您需要确定您正在执行的操作和相关业务流程是否正常。在我们的案例中,这是产品实体的简单更新。
你可能需要做一些测试,以决定最佳的块大小,也限制了并行所以总有资源完成操作。
private void PersistProductChangesInParallel(List<Product> products,
Action<Product, string> productOperationFunc,
string updatedBy)
{
var productsInChunks = products.ChunkBy(20);
Parallel.ForEach(
productsInChunks,
new ParallelOptions { MaxDegreeOfParallelism = 20 },
productsChunk =>
{
try
{
using (var transactionScope = new TransactionScope(
TransactionScopeOption.Required,
new TransactionOptions { IsolationLevel = IsolationLevel.Snapshot }))
{
var dbContext = dbContextFactory.CreatedbContext();
foreach (var Product in productsChunk)
{
dbContext.products.Attach(Product);
productOperationFunc(Product, updatedBy);
}
dbContext.SaveChanges();
transactionScope.Complete();
}
}
catch (Exception e)
{
Log.Error(e);
throw new ApplicationException("Some products might not be updated", e);
}
});
}
@usr你有更好的主意? – Cocowalla 2013-07-05 10:58:31
@Cocowalla不知道OP正在处理的更大场景,我不知道。他的两个解决方案都会导致一个痛苦的实施,这就是为什么我要警告他。也许他可以采用完全不同的路径,并以单线程方式使用EF(它的使用方式)。 – usr 2013-07-05 11:56:40
另外一点需要注意的:你不能做任何更改的实体时,它是分离的,因为没有上下文目前正在跟踪这种变化。 SaveChanges()稍后调用时,更改不会保留。 – JoeCool 2015-01-07 16:38:53