C# 访问Microsoft.SqlServer.Management.Smo.Server对象的成员时,只会崩溃一次

C# 访问Microsoft.SqlServer.Management.Smo.Server对象的成员时,只会崩溃一次,c#,.net,sql-server,C#,.net,Sql Server,我们正在尝试访问Microsoft.SqlServer.Management.Smo.Server对象的DefaultFile成员。经过大量调试后,结果表明,第一次访问成员时会崩溃,但随后可以很好地访问。在调试窗口中查看变量时,第一次返回异常,第二次返回正确的值,以及随后的所有时间 第一次访问server.DefaultFile或server.DefaultLog会引发如下异常: System.IndexOutOfRangeException: Index was outside the bou

我们正在尝试访问
Microsoft.SqlServer.Management.Smo.Server
对象的
DefaultFile
成员。经过大量调试后,结果表明,第一次访问成员时会崩溃,但随后可以很好地访问。在调试窗口中查看变量时,第一次返回异常,第二次返回正确的值,以及随后的所有时间

第一次访问
server.DefaultFile
server.DefaultLog
会引发如下异常:

System.IndexOutOfRangeException: Index was outside the bounds of the array.
 at Microsoft.SqlServer.Management.Smo.BitStorage.SetBit(Int32 itemIndex, BitIndex bitIndex, Boolean value)
 at Microsoft.SqlServer.Management.Smo.PropertyCollection.SetRetrieved(Int32 index, Boolean val)
 at Microsoft.SqlServer.Management.Smo.SqlSmoObject.AddObjectPropsFromDataReader(IDataReader reader, Boolean skipIfDirty, Int32 startColIdx, Int32 endColIdx)
 at Microsoft.SqlServer.Management.Smo.SqlSmoObject.ImplInitialize(String[] fields, OrderBy[] orderby)
 at Microsoft.SqlServer.Management.Smo.SqlSmoObject.Initialize(Boolean allProperties)
 at Microsoft.SqlServer.Management.Smo.SqlSmoObject.OnPropertyMissing(String propname, Boolean useDefaultValue)
 at Microsoft.SqlServer.Management.Smo.PropertyCollection.GetValueWithNullReplacement(String propertyName, Boolean throwOnNullValue, Boolean useDefaultOnMissingValue)
 at Microsoft.SqlServer.Management.Smo.Server.get_DefaultFile()
 at my function... etc etc
第一次访问崩溃非常简单,因此执行以下可怕的操作完全可以解决问题:

using (var sqlConnection = new SqlConnection(sourceDatabaseConnectionString.ConnectionString))
{
    var svrConnection = new ServerConnection(sqlConnection);
    var server = new Server(svrConnection);

    // begin mega hack
    try
    {
        // crashes on first access
        var dummy = server.DefaultFile;
    }
    catch
    {
        // do absolutely nothing
    }
    // end mega hack

    // business as usual...
    var defaultFile = server.DefaultFile;
}

当然,我们不喜欢这样的代码(即使它只是在我们的内部工具中),所以任何关于为什么会发生这种情况的想法都是受欢迎的。我们唯一的线索是,我们最近将SQL Server 2012的一些实例升级为SQL Server 2014。在安装了SQL Server 2014的计算机上本地运行代码时,我们有时可以绕过这个问题。运行此代码的生产计算机根本没有安装,但引用了DLL。但是,在运行代码时调试打印程序集版本时,我们在使用的版本中找不到任何差异。

在使用较旧版本的SMO时,我看到了类似的消息,特别是在尝试使用2008R2 SMO访问2012时。从2008R2 Featurepack SP3升级到安装修复了我的问题


检查共享管理对象+CLR类型+本机客户端驱动程序的最新版本是否可用。

首先,SMO在数据库日期结束时,您是否有权限查看服务器状态/定义?第二:用户数据库文件的默认位置是否与系统数据库文件相同?如果是这样,则DefaultFile和DefaultLog属性永远不会初始化。请参阅,与PowerShell等效的(
if($server.DefaultFile){$server.DefaultFile}或者{$server.InstallDataDirectory+'\'+'Data'}