在使用SMO时,检索IsSystemObject属性将导致性能急剧下降的解决方法
当我们会议为什么使用SMO代替DMO时,一个主要的原因就是增加性能。外加上可以延迟连接到SQL Server,以及限制从对象中得到信息的数量,SMO的性能已经得到了非常大的提高。SMO当建立对象时,仅仅装载非常少的属性。换句话说,这些对象仅仅部分初始化。如果我们以后尝试读取未初始化的属性,SMO会自动请求服务器来获得属性细节。当然,如果错误地使用这些属性,我们可能会迅速丢失通过部分初始化而获得的性能。
本文提供的例子程序充分演示了这种性能丢失的情况。在应用程序中并没有在设计时就显示系统对象,而是在程序运行时通过每个 IsSystemObject 属性来确定每个对象是否为系统对象。不幸的是,这个属性并不是 SMO 的默认装载的属性,而在运行时装载这个属性一般需要花很长的时间。而每次调用对象的 IsSystemObject 都要单独访问 SQL Server 以获得每个对象的属性值,因此,程序的性能将会随着对象的多少而显著下降。
大家不用担心,微软早就为我们考虑到了这一点。虽然IsSystemObject不是系统默认初始化的属性,但我们可以改变这一切,也就是说将IsSystemObject设为默认的属性。在Server类中提供了一个SetDefaultInitFields方法来设置默认属性。下面的代码演示了如何使用SetDefaultInitFields方法来修改Table、View和StoredProcedure类的IsSystemObject属性。要注意的是我们必须为每个对象单独设置IsSystemObject方法。由于本例要使用tables、views和stored procedures的IsSystemObject属性,因此,我们需要调用三次SetDefaultInitFields方法,代码如下:
svr.SetDefaultInitFields(typeof(Table), new string[] { "IsSystemObject" });
svr.SetDefaultInitFields(typeof(Microsoft.SqlServer.Management.Smo.View), new string[] { "IsSystemObject" });
svr.SetDefaultInitFields(typeof(StoredProcedure), new string[] { "IsSystemObject" });
svr.SetDefaultInitFields(typeof(UserDefinedFunction), new string[] { "IsSystemObject" });