代码段:调用 GenericInvoker 前设置参数对象

上次修改时间: 2010年5月6日

适用范围: SharePoint Server 2010

以下代码示例演示在调用 GenericInvoker 之前如何设置 Parameters 对象。

必备组件:

  • Microsoft SharePoint Server 2010 或 Microsoft SharePoint Foundation 2010。

  • Microsoft .NET Framework 3.5 和 Microsoft Visual Studio。

使用该示例

  1. 启动 Visual Studio,然后创建一个 C# 控制台应用程序项目。在创建项目时,选择".NET Framework 3.5"。

  2. 从"视图"菜单中,单击"属性页"以显示项目属性。

  3. 在"生成"选项卡中,为"目标平台"选择"任何 CPU"。

  4. 关闭项目属性窗口。

  5. 在"解决方案资源管理器"中的"引用"下,移除除 System 和 System.Core 之外的所有项目引用。

  6. 将以下引用添加到项目中:

    1. Microsoft.BusinessData

    2. Microsoft.SharePoint

    3. System.Data

    4. System.Web

    5. System.Xml

  7. 用此过程末尾列出的代码替换 Program.cs 中自动生成的代码。

  8. 使用有效值替换 siteUrl、nameSpace、entityName 和 methodInstanceName。

  9. 适当地编辑下面的步骤 4、5 和 6 的代码。在步骤 4、5 和 6 中输入的数据必须与为 BDC 模型中泛型调用程序的方法定义的参数和类型相匹配。

  10. 按 F6 生成解决方案。

  11. 按 Ctrl+F5 运行示例。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.BusinessData.SharedService;
using Microsoft.BusinessData.MetadataModel;
using Microsoft.BusinessData.Runtime;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint;
using System.Web;
using Microsoft.BusinessData.MetadataModel.Collections;
using Microsoft.BusinessData.Infrastructure;

namespace Microsoft.SDK.Sharepoint.Samples
{
    class Program
    {
        static void Main(string[] args)
        {
            string siteURL = "<siteUrl>";
            string entityNS = "<nameSpace>";
            string entityName = "<entityName>";
            string methodInstanceName = "<methodInstanceName>";
            using (SPSite site = new SPSite(siteURL))
            {
                using (new Microsoft.SharePoint.SPServiceContextScope(
                    SPServiceContext.GetContext(site)))
                {
                    BdcService service = 
                        SPFarm.Local.Services.GetValue<BdcService>
                        (String.Empty);
                    IMetadataCatalog catalog = 
                        service.GetDatabaseBackedMetadataCatalog(
                        SPServiceContext.Current);                                      

                    IEntity entity = 
                        catalog.GetEntity(entityNS, entityName);
                    ILobSystemInstance LobSysteminstance = 
                        entity.GetLobSystem().
                        GetLobSystemInstances()[0].Value;

                    // Step 1: Obtain the MethodInstance from Entity.
                    IMethodInstance myGenericInvoker = 
                        entity.GetMethodInstance(
                        methodInstanceName, 
                        MethodInstanceType.GenericInvoker);

                    // Step 2: Obtain the Parameters using the Method.
                    IParameterCollection parameters = 
                        myGenericInvoker.GetMethod().GetParameters();

                    // Step 3: Create the Object[] that needs 
                    // to be passed in.
                    Object[] rawParameters = 
                        new Object[parameters.Count];

                    // Step 4: For simple types and known types you can 
                    // just create the instance and assign it to the 
                    // parameter. 
                    // Known types are the types that are known to you at 
                    // compile time. These are the types that are in .NET Framework,              
                    // BDC, or assemblies in the global assembly cache. The types that are 
                    // defined in your proxy are NOT known types, as BDC 
                    // will generate another proxy for the Web service. 
                    rawParameters[0] = 32;
                    rawParameters[1] = "A";
                    rawParameters[2] = new System.Data.DataTable("X");

                    // Step 5: For "unknown types" (such as types defined 
                    // in your proxy), you need to access to the type 
                    // reflector to instantiate the complex types 
                    // defined in your proxy.
                    ITypeReflector reflector = parameters[3].TypeReflector;
                    ITypeDescriptor rootTypeDescriptor = 
                        parameters[3].GetRootTypeDescriptor();
                    Object instance = reflector.Instantiate(
                        rootTypeDescriptor);
                    // Or if you want to have the instance object 
                    // use default values 
                    // defined in your model, use the following:
                    // Object instance = 
                    //     reflector.Instantiate(
                    //         rootTypeDescriptor, myGenericInvoker); 
                    // Or if the root of the parameter is a collection, 
                    // use the following:
                    // Object instance = 
                    //     reflector.Instantiate(rootTypeDescriptor, 55); 
                    // Or if the root of the parameter is a collection 
                    // and you want to use default values, 
                    // use the following: 
                    // Object instance = 
                    //     reflector.Instantiate(
                    //     rootTypeDescriptor, 55, myGenericInvoker); 

                    rawParameters[3] = instance;

                    // Step 6: To set values in the complex object 
                    // you’ve just created, you can use the Set
                    // method on TypeReflector.
                    ITypeDescriptor child = 
                        rootTypeDescriptor.GetChildTypeDescriptors()[3];
                    // Alternatively you can look over them and 
                    // check the name, 
                    // but since you are using generic invoker, 
                    // it is most likely that you have intimate 
                    // knowledge of the method.
                    // If your object is a structure:
                     reflector.Set(
                        child, rootTypeDescriptor, ref instance, "value"); 
                    // Or if your object is a collection:
                    // reflector.Set(
                    //     child, rootTypeDescriptor, ref instance, 
                    // "value", /*index*/ 2); 
                    // If you want to set values in deeper parts of 
                    // the structure, you’ll need to navigate to the 
                    // relevant type descriptors, 
                    // and provide the corresponding root object, 
                    // parent type descriptor and child type descriptor. 
                    // You can also create instances of deeper 
                    // TypeDescriptors and assign the created instances 
                    // to parts of the structure using the Set method.

                    // NOTE: Repeat steps 5 and 6 for all the values 
                    // you need to create and set.

                }
            }
        }
    }
}

一个有用的快捷方式是使用 IMethodInstance.GetMethod().CreateDefaultParameterInstances(IMethodInstance),它将根据模型中的默认值返回完全实例化的后端参数的 Object[],然后使用 TypeReflector 重写或更改这些默认值,如以下代码中所示。CreateDefaultParameterInstances() 是前面的步骤 3 至 5 的快捷方式。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.BusinessData.SharedService;
using Microsoft.BusinessData.MetadataModel;
using Microsoft.BusinessData.Runtime;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint;
using System.Web;

namespace Microsoft.SDK.Sharepoint.Samples
{
    class Program
    {
        static void Main(string[] args)
        {
            string siteURL = ""<siteUrl>";
            string entityNS = "<nameSpace>";
            string entityName = "<entityName>";
            string methodInstanceName = "<methodInstanceName>";
            using (SPSite site = new SPSite(siteURL))
            {
                using (new Microsoft.SharePoint.SPServiceContextScope(
                    SPServiceContext.GetContext(site)))
                {
                    BdcService service = 
                        SPFarm.Local.Services.GetValue<BdcService>(
                        String.Empty);
                    IMetadataCatalog catalog = 
                        service.GetDatabaseBackedMetadataCatalog(
                        SPServiceContext.Current);

                    IEntity entity = catalog.GetEntity(
                        entityNS, entityName);
                    ILobSystemInstance LobSysteminstance = 
                        entity.GetLobSystem().GetLobSystemInstances()
                        [0].Value;

                    // Step 1: Obtain the MethodInstance from the entity.
                    IMethodInstance myGenericInvoker = 
                        entity.GetMethodInstance(
                        methodInstanceName, MethodInstanceType.GenericInvoker);

                    // Step 2: Obtain the Parameters using the Method.
                    IParameterCollection parameters = 
                        myGenericInvoker.GetMethod().
                        CreateDefaultParameterInstances(IMethodInstance);
                }
            }
        }
    }
}

请参阅

引用

BdcService

Services

IMetadataCatalog

GetDatabaseBackedMetadataCatalog(SPServiceContext)

GetEntity(String, String)

IEntity

GetLobSystem()

GetLobSystemInstances()

ILobSystemInstance

GetMethodInstance(String, MethodInstanceType)

IMethodInstance

IParameterCollection

CreateDefaultParameterInstances(IMethodInstance)