web-dev-qa-db-fra.com

Pourquoi c # smo peut-il voir des propriétés étendues sur une colonne mais PowerShell SMO peut?

Je tente de lire des propriétés étendues sur des tables et des colonnes dans une application Winforms C #. J'utilise SQL Server SMO pour le faire. Lorsque j'exécute l'application, il ne voit pas les propriétés étendues, mais lorsque je lis les propriétés étendues à l'aide de PowerShell, cela voit les propriétés étendues.

Le code C #:

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

Le code 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

J'ai vérifié et que Visual Studio et PowerShell utilisent la même version de SMO (11.0.0.0). Quand j'exécute le code C # le Col.extEverProperties.count = 0, mais quand j'exécute le code PowerShell, je reçois:

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

Quelqu'un a-t-il des idées sur la raison pour laquelle cela pourrait se produire?

Informations Complémentaires

Dans le code C #, j'ouvre un digne d'information sur une table en utilisant:

sourceServer.ConnectionContext.ExecuteReader(<select command>)

récupérer les données de la table. Je passe ensuite dans une boucle de temps avec DigneAreader et à l'intérieur de cette boucle, j'ai:

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

Lorsque je passe à travers le foreach, la variable sourceTable a sa propriété étendue, mais la variable de colonne col ne le fait pas.

7
Wayne E. Pfeffer

Je veux juste shadow @Bradc un peu. J'ai testé son code sur Visual Studio 2015 (Mise à jour 3) sur une machine Windows 10 Pro X64 contre une instance SQL Server 2014 et je peux confirmer que vous pouvez obtenir des propriétés étendues d'un champ sans problème.

Pour reproduire, j'utilise l'une de mes bases de données locales. J'ai utilisé le suivant Code Snip pour définir des propriétés étendues.

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

J'ai créé un nouveau projet de console et ajouté les références suivantes:

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

À partir de:

\% Installation Path%\Microsoft SQL Server\130\SDK\assemblages \

Donc, tout mon code, basé sur @ Bradc's ressemble à:

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

Bien sûr, vous pouvez maintenant accéder aux propriétés et utiliser leurs valeurs.

La valeur de comptage qui ne fonctionnait pas sur votre exemple:

enter image description here

2
Nelz

Vous n'avez pas montré votre code qui instanciait l'objet col, pouvons-nous voir ce code?

Utiliser quelque chose comme DigneAreader GetSchemaTable() méthode ne pas renvoyer le réel (SQL SMO) (SQL SMO) Objet de la table, il renvoie une nouvelle table avec de nombreuses propriétés de colonne utiles, mais (autant que je sache, cela n'inclut pas les propriétés étendues.

jetez un coup d'œil à cette réponse de Stackoverflow de Christopher Klein . Si je lis ce droit, cela devrait renvoyer un objet objet de table SQL SMO, que je pense vous permettra de récupérer des propriétés de colonne étendues, quelque chose comme :

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());
            } 
        }
    }
}

Si cela ne fonctionne pas, il suffit de rester avec votre version de PowerShell de travail ou de votre recours à ne des autres idées de cette réponse associée .

1
BradC