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

发布于 2024-09-16 06:18:57 字数 1381 浏览 4 评论 0原文

我是 .Net 编程新手,想知道反射是否适合遍历对象以发现类实例中的集合。

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

计划是连接到数据库,确定存在哪些集合,然后对于每个集合,如果该集合公开实现 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...

如果可能的话,我想用一个函数枚举数据库中的所有对象

I am new to .Net Programming and would like to know if Reflection is suitable for traversing an Object to discover Collections within an instance of a class.

I am working with the Microsoft.SqlServer.Management.Smo Namespace.

The plan is to connect to a database, determine what collections exists, then for each of those collections, if the Collection exposes objects which implement the IScriptable Interface, generate a script for the object.

How do i do the following (This is pseudo-code as I am seeking assistance with using reflection or some other method to do the following)

    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

So far I am able to connect to the database and script out Tables by doing the following.

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

The reason I want to change this, is different versions of SQL Server will contain different collections of objects. Instead of writing code for each type.

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

I would like to enumerate all objects in db with one function if possible

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

甚是思念 2024-09-23 06:18:57

恐怕这是 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 集合不是通用的,因此不可能仅找到这些集合)包含可编写脚本的对象)。

I'm afraid this is C# rather than VB.net but hopefully you'll be able to interpret it?

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

The key is to ue IsAssignableFrom to find the collection properties and then to only extract the objects in those collections that implement the IScripable interface (since the SMO collections are not generic, it's not possible to find ony those collections that contain scriptable objects).

原来分手还会想你 2024-09-23 06:18:57

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

It sounds like all you need is to determine if an object implements a given interface. If so then reflection is not the right tool. Instead you want to use the VB.Net TypeOf operator (it's meant for this very test).

If TypeOf collection_object is IScriptable Then 

Full example

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文