如何获取包含在C#或VB.net中实现接口的对象的集合列表

时间:2010-08-28 21:43:28

标签: c# sql-server vb.net reflection smo

我是.Net Programming的新手,想知道Reflection是否适合遍历Object以发现类实例中的集合。

我正在使用Microsoft.SqlServer.Management.Smo命名空间。

计划是连接到数据库,确定存在哪些集合,然后对于每个集合,如果Collection公开实现IScriptable Interface的对象,则为该对象生成脚本。

我如何执行以下操作(这是伪代码,因为我正在寻求使用反射或其他方法执行以下操作的帮助)

    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...

如果可能的话,我想用db中的所有对象枚举

2 个答案:

答案 0 :(得分:1)

我担心这是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集合不是通用的,所以不可能找到那些集合包含可编写脚本的对象。)

答案 1 :(得分:0)

听起来你需要的只是确定一个对象是否实现了一个给定的接口。如果是这样,那么反射就不是正确的工具。相反,你想使用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