/// <summary> /// Get the fields that have been defined for the return entity of a method. /// </summary> /// <param name="methodInstance">The method to examine.</param> /// <returns>A collection of fields defined on the return entity of the the method.</returns> protected virtual ITypeDescriptorCollection GetEntityFields(Microsoft.BusinessData.MetadataModel.IMethodInstance methodInstance) { ITypeDescriptor returnType = methodInstance.GetReturnTypeDescriptor(); ITypeDescriptorCollection entityFields = null; if (returnType.IsCollection) { ITypeDescriptorCollection childTypes = returnType.GetChildTypeDescriptors(); if (childTypes.Count > 0) { entityFields = childTypes[0].GetChildTypeDescriptors(); } } else { entityFields = returnType.GetChildTypeDescriptors(); } return(entityFields); }
/// <summary> /// Executes a MethodInstance in the model against the specified external system instance with given parameters. /// </summary> /// <param name="methodInstance">The method instance being executed.</param> /// <param name="lobSystemInstance">The external system instance which the method instance is being executed against.</param> /// <param name="args">Parameters of the method. The size of the parameter array is equal to the number of parameter objects in the method definition in the BCS model file, and the values are passed in order. Out and return parameters will be a null reference.</param> /// <param name="context">ExecutionContext in which this execution is happening. This value will be a null reference if ExecutionContext is not created.</param> /// <remarks> /// This method is executed in a separate thread. /// </remarks> public override void ExecuteStatic(Microsoft.BusinessData.MetadataModel.IMethodInstance methodInstance, Microsoft.BusinessData.MetadataModel.ILobSystemInstance lobSystemInstance, object[] args, Microsoft.BusinessData.Runtime.IExecutionContext context) { // Modify the execution behaviour for the method instance types that are used in the Glyma repository model and revert to the base class implementation // for all other method instance types (until a better understanding is developed on how the other method instance types are used). switch (methodInstance.MethodInstanceType) { case MethodInstanceType.Finder: case MethodInstanceType.SpecificFinder: case MethodInstanceType.AssociationNavigator: case MethodInstanceType.ChangedIdEnumerator: case MethodInstanceType.DeletedIdEnumerator: case MethodInstanceType.BinarySecurityDescriptorAccessor: // Validate parameters to ensure all required execution details are available. if (methodInstance == null) { throw new ArgumentNullException("methodInstance"); } if (lobSystemInstance == null) { throw new ArgumentNullException("lobSystemInstance"); } if (args == null) { throw new ArgumentNullException("args"); } if (context == null) { throw new ArgumentNullException("context"); } IConnectionContext connectionContext = (IConnectionContext)context["ConnectionContext"]; if (connectionContext == null) { throw new ArgumentNullException("The BDC execution context doesn't contain a connection context."); } // Create the proxy and execute the method. GlymaRepositoryProxy proxy = null; try { proxy = CreateProxy(); if (proxy == null) { throw new ArgumentException("The proxy returned from the BDC shim is null."); } GlymaSearchLogger.WriteTrace(LogCategoryId.Connector, TraceSeverity.Verbose, "Configuring proxy to execute " + methodInstance.MethodInstanceType.ToString() + " method for: " + connectionContext.Path.OriginalString); SetGlobalSettings(proxy, lobSystemInstance.GetLobSystem().GetProperties()); SetStartAddress(proxy, connectionContext.Path.OriginalString); SetRepositoryName(proxy, lobSystemInstance.Name); SetMapConnectionString(proxy, lobSystemInstance.GetProperties(), lobSystemInstance.Name); // Get the definition of the fields for the entity that will be returned by the proxy method. This enables the connector to build entities // based on the definitions in the model file instead of having entities with fixed pre-defined properties. ITypeDescriptorCollection entityFields = GetEntityFields(methodInstance); GlymaSearchLogger.WriteTrace(LogCategoryId.Connector, TraceSeverity.Verbose, "Executing " + methodInstance.MethodInstanceType.ToString() + " proxy method for: " + connectionContext.Path.OriginalString); ExecuteProxyMethod(proxy, methodInstance, args, entityFields); GlymaSearchLogger.WriteTrace(LogCategoryId.Connector, TraceSeverity.Verbose, "Completed execution of " + methodInstance.MethodInstanceType.ToString() + " proxy method for: " + connectionContext.Path.OriginalString); } catch (Exception currentException) { GlymaSearchLogger.WriteTrace(LogCategoryId.Connector, TraceSeverity.Unexpected, currentException.ToString()); throw; } finally { if (proxy != null) { DisposeProxy(proxy); proxy = null; } } break; default: base.ExecuteStatic(methodInstance, lobSystemInstance, args, context); break; } }