web-dev-qa-db-ja.com

C#SMOが列の拡張プロパティを表示できないのに、Powershell SMOはなぜ表示できるのですか?

Winforms C#アプリケーションでテーブルと列の拡張プロパティを読み取ろうとしています。 SQL Server SMOを使用しています。アプリケーションを実行しても、拡張プロパティは表示されませんが、PowerShellを使用して拡張プロパティを読み取ると、拡張プロパティが表示されます。

C#コード:

var x = col.ExtendedProperties.Count;
var NPI = col.ExtendedProperties["NPI"].Value;
bool npi = bool.Parse(NPI.ToString());

PowerShellコード:

Add-Type -AssemblyName "Microsoft.SqlServer.Smo, Version=11.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91"
$server = New-Object Microsoft.SqlServer.Management.Smo.Server $env:COMPUTERNAME
$server.Databases["<db name>"].Tables["<table name>"].Columns["<column name>"].ExtendedProperties | Select Name, Value, State

チェックしましたが、Visual StudioとPowerShellの両方で同じバージョンのSMO(11.0.0.0)を使用しています。 C#コードを実行するとcol.ExtendedProperties.Count = 0ですが、PowerShellコードを実行すると次のようになります。

Name Value    State
---- -----    -----
NPI  False Existing

なぜこれが起こり得るのかについて誰かが何か考えを持っていますか?

追加情報

C#コードで、次のコマンドを使用してテーブルのDataReaderを開きます。

sourceServer.ConnectionContext.ExecuteReader(<select command>)

テーブルからデータを取得します。次に、DataReaderを使用してwhileループに入り、そのwhileループ内で次のようにしています。

foreach (Column col in sourceTable.Columns) 
{ 
StringBuilder cleanData = CleanseColumn(col, dr[col.Name].ToString());
sbvalues.Append("'" + cleanData + "', "); 
}

foreachをステップ実行すると、sourceTable変数には拡張プロパティがありますが、col列変数にはありません。

7

@BradCを少しシャドウしたいだけです。私はSQL Server 2014インスタンスに対してWindows 10 Pro x64マシンのVisual Studio 2015(Update 3)で彼のコードをテストしましたが、問題なくフィールドの拡張プロパティを取得できることを確認できました。

複製するには、ローカルデータベースの1つを使用します。 following コードを使用して、いくつかの拡張プロパティを定義しました。

USE MyLocalDb;
GO
EXEC sys.sp_addextendedproperty 
@name = N'MS_DescriptionExample', 
@value = N'Some EP example.', 
@level0type = N'SCHEMA', @level0name = dbo, 
@level1type = N'TABLE',  @level1name = tblATableWithAtblPrefix,
@level2type = N'COLUMN', @level2name = Forename;
GO

新しいコンソールプロジェクトを作成し、次の参照を追加しました。

Microsoft.SqlServer.ConnectionInfo
Microsoft.SqlServer.Management.Sdk.Sfc
Microsoft.SqlServer.Smo
Microsoft.SqlServer.SqlEnum

すべてから:

\%インストールパス%\ Microsoft SQL Server\130\SDK\Assemblies \

したがって、@ BradCに基づく私のコード全体は次のようになります。

using System;
using System.Data.SqlClient;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Common;

namespace ConsoleApplication7
{
    class Program
    {
        private static Database database;
        static void Main(string[] args)
        {
            Microsoft.SqlServer.Management.Smo.Server server;

            SqlConnection connection = new SqlConnection("Integrated Security=SSPI; Data Source=SIS_DBA");
            Microsoft.SqlServer.Management.Common.ServerConnection serverConnection = 
                new Microsoft.SqlServer.Management.Common.ServerConnection(connection);

            server = new Server(serverConnection);

            database = server.Databases["ImmigSql"];

            foreach (Table table in database.Tables)
            {
                Console.WriteLine(" " + table.Name);
                foreach (Column col in table.Columns)
                {
                    Console.WriteLine("  " + col.Name + " " + col.DataType.Name);
                    foreach (var property in col.ExtendedProperties)
                    {
                        Console.WriteLine(" " + property.ToString() + "");
                    }
                }
            }
            Console.ReadLine();
        }
    }
}

enter image description here

もちろん、プロパティにアクセスしてその値を使用することができます。

例で機能しなかったCount値:

enter image description here

2
Nelz

colオブジェクトをインスタンス化するコードを示していません。そのコードを確認できますか?

データリーダーの GetSchemaTable() method のようなものを使用しても、実際にはactualは返されません(SQL SMO)テーブルオブジェクト、それは多くの有用な列プロパティを持つ新しいテーブルを返しますが、(私が見る限り)拡張プロパティを含みません。

クリストファークラインによるこのStackOverflowの回答を見てください 。私がその権利を読んでいる場合、actualSQL SMOテーブルオブジェクトが返されるはずです。これにより、次のような拡張列プロパティを取得できると思います:

using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SqlClient;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Smo.Agent;


// Add references: (in c:\Program Files\Microsoft SQL Server\90\SDK\Assemblies\)
// Microsoft SqlServer.ConnectionInfo
// Microsoft SqlServer.Management.Sdk.Sfc
// Microsoft SqlServer.Smo

namespace SMO
{
    class Program
    {
        static Database db;

        static void Main(string[] args)
        {
            Microsoft.SqlServer.Management.Smo.Server server;

            SqlConnection sqlConnection = new SqlConnection(@"Integrated Security=SSPI; Data Source=LOCAL");
            //build a "serverConnection" with the information of the "sqlConnection"
            Microsoft.SqlServer.Management.Common.ServerConnection serverConnection =
              new Microsoft.SqlServer.Management.Common.ServerConnection(sqlConnection);

            //The "serverConnection is used in the ctor of the Server.
            server = new Server(serverConnection);

            db = server.Databases["TestDB"];

            Table tbl;
            tbl = db.Tables["Sales"];

            //warning, not tested, your code goes here
            foreach (Column col in tbl.Columns)
            {
               var x = col.ExtendedProperties.Count;
               var NPI = col.ExtendedProperties["NPI"].Value;
               bool npi = bool.Parse(NPI.ToString());
            } 
        }
    }
}

それがうまくいかない場合は、作業中のPowerShellバージョンをそのまま使用するか、または この関連する回答の他のアイデアの1つ に頼ってください。

1
BradC