2011-09-20 43 views
7

linq-to-sql datacontext如何使数据库连接保持打开状态?Linq-to-sql上下文数据库连接处理

当我们对每个更新实体的一个SubmitChanges()而不是一个SubmitChanges()对整个批次实体的性能进行了一些测试时,问题出现了。结果:

插入一个的SubmitChanges 3000项()调用...时间:1318ms

插入3000个项目中一个的SubmitChanges()调用,内 的TransactionScope ...时间:1280ms

在个别的SubmitChanges插入3000个项目()调用...时间: 4377ms

插入个别的SubmitChanges 3000个项目()一 交易...时间内电话:2901ms

请注意,每个改变实体做个人SubmitChanges()时,把一个交易内的所有改进性能,这是相当意外给我们。在sql server分析器中,我们可以看到事务中的个人SubmitChanges()调用不会为每个调用重置数据库连接,而不是没有事务的调用。

数据上下文在什么情况下保持连接打开?有没有关于linq-to-sql如何处理连接的详细文档?

回答

3

您并未显示全部图片;默认情况下,LINQ-to-SQL将在事务中包装一个调用SubmitChanges。如果您使用其他交易进行包装,则不会看到连接重置;直到SubmitChanges调用的所有完成,然后才提交外部事务。

3

除了打开/关闭连接时,可能有许多因素可能影响计时。

编辑:我已经实现了linq2sql如何分别管理缓存实体和脏实体后删除了有关跟踪实体的位。

通过使用Reflector或其他反汇编程序来检查SqlConnectionManager类中的方法,您可以很好地了解连接的管理方式。 SubmitChanges会在提交后调用其IProvider上的ClearConnection(通常是SqlProvider,然后使用SqlConnectionManager),如果它将提交包装在自己的事务中,而不是如果SubmitChanges是更大事务的一部分。当连接打开和关闭时,取决于是否有其他活动正在使用SqlConnectionManager。

+0

DataContext确实跟踪已更改的对象,但在默认生成的代码中(通过本例中的dbml设计器),它使用INotifyPropertyChanging和INotifyPropertyChanged。通过这些实现,不需要遍历所有对象。无论如何你是对的,跟踪的实体数量增长很大。 –

0

我最近也搞砸了。调用SubmitChanges 3000次并不是一个好主意,但根据每条记录被插入的重要性,您可能想要这样做,毕竟只需要1000毫秒。

交易范围和多个SubmitChanges是我所期望看到的。由于你仍然在一个事务中,我期望看到SQL服务器处理这个更好,这似乎。一个SubmitChanges并使用显式/隐式TransactionScope似乎产生相同的结果,这是可以预料的。那里不应该有任何性能差异。

我觉得需要的时候连接创建的,但你要记住,这将您的提供商内汇集所以,除非您的连接字符串是变化的,你应该钩挂在同一个连接池,这将产生相同的性能,无论做法。由于LINQ-SQL使用SqlConnection在幕后,关于它的一些信息在以下几点:

http://msdn.microsoft.com/en-us/library/8xx3tyca(VS.80).aspx

如果你的后蛮力的性能,看移动到一个存储Proceedure用于插入带有明确TransactionScope。如果速度不够快,请使用SqlBulkCopy。 3000行应插入速度超过1000毫秒。