Как получить список коллекций, которые содержат объекты, которые реализуют интерфейс в C # или VB.net - PullRequest
1 голос
/ 29 августа 2010

Я новичок в .Net Programming и хотел бы знать, подходит ли Reflection для обхода объекта для обнаружения коллекций в экземпляре класса.

Я работаю с Microsoft.SqlServer.Management.Smo Namespace.

Планируется подключиться к базе данных, определить, какие коллекции существуют, а затем для каждой из этих коллекций, если Коллекция предоставляет объекты, которые реализуют интерфейс IScriptable, сгенерировать сценарий для объекта.

Как мне сделать следующее (Это псевдокод, поскольку я ищу помощи в использовании рефлексии или другого метода для выполнения следующих действий)

    Imports Microsoft.SqlServer.Management.Smo
    Imports Microsoft.SqlServer.Management.Smo.Agent
    Imports Microsoft.SqlServer.Management.Common

    Dim db as Database
    ...
' 1. How do I determine all Collections in the db Object I have created, which implement the IScriptable Interface.

    For each myCollection as Collection in db.Database.?Collections?
        For each collection_object in myCollection

       If collection_object.GetInterface("IScriptable") IsNot Nothing Then
          ScriptObjectCreate(collection_object, destFolder & "\" & TypeOf(collection_object).toString() & "\", False)
       End If
    Next
Next

Пока я могу подключиться кТаблицы базы данных и сценария выполняются следующим образом.

For Each obj As Table In db.Tables
                If Not (obj.IsSystemObject) Then
                    ScriptObjectCreate(obj, destFolder & "\" & "Tables\", False)
                End If
Next

Причина, по которой я хочу изменить это, состоит в том, что разные версии SQL Server будут содержать разные коллекции объектов.Вместо написания кода для каждого типа.

For each obj as Table
For each obj as StoredProcedure 
For each obj as Trigger
etc...

Я бы хотел перечислить все объекты в БД с одной функцией, если это возможно

Ответы [ 2 ]

1 голос
/ 29 августа 2010

Боюсь, это C #, а не VB.net, но, надеюсь, вы сможете его интерпретировать?

Server server = new Server();
Database database = server.Databases["ReportServer"];

foreach (PropertyInfo propertyInfo in typeof(Database).GetProperties())
{
    if (typeof(SchemaCollectionBase).IsAssignableFrom(propertyInfo.PropertyType))
    {
        SchemaCollectionBase collection = (SchemaCollectionBase)propertyInfo.GetValue(database, null);

        foreach (IScriptable item in collection)
        {
            PropertyInfo isSystemObjectPropertyInfo = item.GetType().GetProperty("IsSystemObject");

            if (isSystemObjectPropertyInfo == null || !(bool)isSystemObjectPropertyInfo.GetValue(item, null))
            {
                Console.WriteLine("{0} is scriptable and not a system object", item);
                // TODO: ScriptObjectCreate(item, destFolder + "\\" + item.GetType() + "\\", false);
            }
        }
    }
}

Ключ в том, чтобы IsAssignableFrom найти свойства коллекции, а затемтолько для извлечения объектов из тех коллекций, которые реализуют интерфейс IScripable (поскольку коллекции SMO ​​не являются общими, невозможно найти только те коллекции, которые содержат объекты с возможностью сценариев).

0 голосов
/ 29 августа 2010

Похоже, все, что вам нужно, это определить, реализует ли объект данный интерфейс.Если это так, то отражение не является правильным инструментом.Вместо этого вы хотите использовать оператор VB.Net TypeOf (он предназначен именно для этого теста).

If TypeOf collection_object is IScriptable Then 

Полный пример

For each myCollection as Collection in db.Database.Collections
   For each collection_object in myCollection
     if TypeOf collection_object is IScriptable Then ..
      ScriptObjectCreate(collection_object, destFolder & "\" & TypeOf(collection_object).toString() & "\", False)
     End If
   Next
Next
...