/// <summary> /// Get the instance of a Business Data Connectivity entity /// </summary> /// <param name="site"></param> /// <param name="nameSpace"></param> /// <param name="entityName"></param> /// <param name="entityId"></param> /// <returns></returns> private static IEntityInstance GetEntityInstance(SPSite site, string nameSpace, string entityName, string entityId) { //Use the scope of the currently opened site SPServiceContext ctx = SPServiceContext.GetContext(site); SPServiceContextScope scope = new SPServiceContextScope(ctx); //Get the BDC service of the local SP farm BdcService service = SPFarm.Local.Services.GetValue <BdcService>(); IMetadataCatalog catalog = service.GetDatabaseBackedMetadataCatalog(ctx); IEntity entity = catalog.GetEntity(nameSpace, entityName); ILobSystemInstance LobSysteminstance = entity.GetLobSystem().GetLobSystemInstances()[0].Value; IEntityInstance entInstance = null; //Loop through the methods defined in the LOB foreach (KeyValuePair <string, IMethod> method in entity.GetMethods()) { IMethodInstance methodInstance = method.Value.GetMethodInstances()[method.Key]; //Get the Specific Finder method of the LOB if (methodInstance.MethodInstanceType == MethodInstanceType.SpecificFinder) { //Find the record with the ID from the datasource Microsoft.BusinessData.Runtime.Identity id = new Microsoft.BusinessData.Runtime.Identity(entityId); entInstance = entity.FindSpecific(id, entity.GetLobSystem().GetLobSystemInstances()[0].Value); } } return(entInstance); }
/// <summary> /// Executes the proxy method using reflection. /// </summary> /// <param name="proxy">A GlymaRepositoryProxy object used to execute the method.</param> /// <param name="methodInstance">The method to execute.</param> /// <param name="methodArgs">The parameters of the method.</param> /// <param name="entityFields">A ITypeDescriptorCollection object that contains the fields to retrieve for the entity containing the method to execute.</param> protected virtual void ExecuteProxyMethod(GlymaRepositoryProxy proxy, IMethodInstance methodInstance, object[] methodArgs, ITypeDescriptorCollection entityFields) { // Extract the method details required to execute it using reflection. IMethod method = methodInstance.GetMethod(); string methodName = (method.LobName != null) ? method.LobName : method.Name; List <Type> parameterTypes = new List <Type>(); List <object> parameters = new List <object>(methodArgs.Length); IParameterCollection parameterDefinitions = method.GetParameters(); foreach (IParameter parameterDefinition in parameterDefinitions) { if (parameterDefinition.Direction != DirectionType.Return) { Type parameterType = parameterDefinition.TypeReflector.ResolveDotNetType(parameterDefinition.GetRootTypeDescriptor().TypeName, method.GetDataClass().GetLobSystem()); if (parameterDefinition.Direction != DirectionType.In) { parameterType = parameterType.MakeByRefType(); } parameters.Add(methodArgs[parameterDefinition.OrdinalNumber]); parameterTypes.Add(parameterType); } } // Pass the entity fields as the last parameter to the proxy method. parameters.Add(entityFields); parameterTypes.Add(typeof(ITypeDescriptorCollection)); // Execute the method using reflection. object[] parametersArray = parameters.ToArray(); MethodInfo proxyMethodInfo = typeof(GlymaRepositoryProxy).GetMethod(methodName, BindingFlags.Public | BindingFlags.Instance, null, parameterTypes.ToArray(), null); if (proxyMethodInfo == null) { throw new Microsoft.BusinessData.Runtime.RuntimeException("A method with the name \"" + methodName + "\" with the specified parameters could not be found in the proxy."); } object result = proxyMethodInfo.Invoke(proxy, parametersArray); // Set the parameter values using the results of the method execution. foreach (IParameter parameterDefinition in parameterDefinitions) { if (parameterDefinition.Direction == DirectionType.Return) { methodArgs[parameterDefinition.OrdinalNumber] = result; } else { methodArgs[parameterDefinition.OrdinalNumber] = parametersArray[parameterDefinition.OrdinalNumber]; } } }
private static void SetSecondaryFields(SPListItem listItem, SPBusinessDataField dataField, IEntityInstance entityInstance, string finderMethod) { try { // Convert the entity to a formatted datatable System.Data.DataTable dtBDCData = entityInstance.EntityAsFormattedDataTable; // Set the BCS field itself (Display Value) listItem[dataField.Id] = dtBDCData.Rows[0][dataField.BdcFieldName].ToString(); // Get the specific finder method to get the columns that returns IMethodInstance method = entityInstance.Entity.GetMethodInstances(MethodInstanceType.SpecificFinder)[finderMethod]; ITypeDescriptorCollection oDescriptors = method.GetReturnTypeDescriptor().GetChildTypeDescriptors()[0].GetChildTypeDescriptors(); // Set the column names to the correct values foreach (ITypeDescriptor oType in oDescriptors) { if (oType.ContainsLocalizedDisplayName()) { if (dtBDCData.Columns.Contains(oType.Name)) { dtBDCData.Columns[oType.Name].ColumnName = oType.GetLocalizedDisplayName(); } } } // Get the secondary field display names - these should be set string[] sSecondaryFieldsDisplayNames = dataField.GetSecondaryFieldsNames(); // Loop through the fields and set each column to its value foreach (string columnNameInt in sSecondaryFieldsDisplayNames) { foreach (SPField field in listItem.Fields) { if (field.Title.StartsWith(dataField.Title) && field.GetProperty("BdcField") == columnNameInt) { Guid gFieldID = listItem.Fields[field.Title].Id; listItem[gFieldID] = dtBDCData.Rows[0][columnNameInt].ToString(); } } } } catch (Exception e) { LogError("SetSecondaryFields errored with message " + e.Message, ErrorLevel.Warning); throw; } }
/// <summary> /// Set the secondary fields of a BDC field /// </summary> /// <param name="listItem"></param> /// <param name="dataField"></param> /// <param name="entityInstance"></param> private static void SetSecondaryFields(SPListItem listItem, SPBusinessDataField dataField, IEntityInstance entityInstance) { //Copy the fieldset to a datatable DataTable dtBDCData = entityInstance.EntityAsFormattedDataTable; //Update the BDC primary field ID with the primary field in the datatable listItem[dataField.Id] = dtBDCData.Rows[0][dataField.BdcFieldName].ToString(); //Get the Specific Finder method of the BDC entity and get the collection of columns/descriptors IMethodInstance method = entityInstance.Entity.GetMethodInstances(MethodInstanceType.SpecificFinder)[0].Value; ITypeDescriptorCollection oDescriptors = method.GetReturnTypeDescriptor().GetChildTypeDescriptors()[0].GetChildTypeDescriptors(); //Loop through each Type Descriptor in the specific finder instance and update the local datatable column names appropriately foreach (ITypeDescriptor oType in oDescriptors) { if (oType.ContainsLocalizedDisplayName()) { if (dtBDCData.Columns.Contains(oType.Name)) { dtBDCData.Columns[oType.Name].ColumnName = oType.GetLocalizedDisplayName(); } } } //Loop through each column name in the data source and update the corresponding list item column string[] sSecondaryFieldsDisplayNames = dataField.GetSecondaryFieldsNames(); foreach (string columnNameint in sSecondaryFieldsDisplayNames) { Guid gFieldID = listItem.Fields[String.Format("{0}: {1}", dataField.Title, dtBDCData.Columns[columnNameint].Caption)].Id; listItem[gFieldID] = dtBDCData.Rows[0][columnNameint].ToString(); } //Set the final values of the list item linking the item to its actual BDC Identity (allows for manually refreshing the list) listItem[dataField.Id] = dtBDCData.Rows[0][dataField.BdcFieldName].ToString(); listItem[dataField.RelatedField] = dtBDCData.Rows[0]["BdcIdentity"].ToString(); }
static void ExecuteBcsEctMethods(string siteUrl) { using (SPSite site = new SPSite(siteUrl)) { using (new SPServiceContextScope(SPServiceContext.GetContext(site))) { BdcServiceApplicationProxy proxy = (BdcServiceApplicationProxy)SPServiceContext.Current.GetDefaultProxy(typeof(BdcServiceApplicationProxy)); DatabaseBackedMetadataCatalog model = proxy.GetDatabaseBackedMetadataCatalog(); IEntity entity = model.GetEntity("EmployeeEntityModel.BdcModel1", "Entity1"); // Namespace, Entity name ILobSystemInstance lobSystemInstance = entity.GetLobSystem().GetLobSystemInstances()[0].Value; IMethodInstance method = entity.GetMethodInstance("ReadList", MethodInstanceType.Finder); // Finder method name IView view = entity.GetFinderView(method.Name); IFilterCollection filterCollection = entity.GetDefaultFinderFilters(); IEntityInstanceEnumerator entityInstanceEnumerator = entity.FindFiltered(filterCollection, method.Name, lobSystemInstance, OperationMode.Online); Console.WriteLine("Employee Login ID | Job Title"); while (entityInstanceEnumerator.MoveNext()) { Console.WriteLine(entityInstanceEnumerator.Current["LoginID"].ToString() + " - " + entityInstanceEnumerator.Current["JobTitle"].ToString()); // Column names } Console.ReadLine(); } } }
private static IEntityInstance GetEntityInstance(SPBusinessDataField dataField, string entityId, SPSite site, SPListItem item, string finderMethodName) { IEntityInstance entInstance = null; try { IEntity entity = GetEntity(site, dataField); ILobSystemInstance lobSystemInstance = entity.GetLobSystem().GetLobSystemInstances()[0].Value; // Get methods collection foreach (KeyValuePair <string, IMethod> method in entity.GetMethods()) { // Get current method's instance IMethodInstance methodInstance = method.Value.GetMethodInstances()[method.Key]; // Execute specific finder method if (methodInstance.MethodInstanceType == MethodInstanceType.SpecificFinder && methodInstance.Name == finderMethodName) { Identity id = null; if (EntityInstanceIdEncoder.IsEncodedIdentifier(entityId)) { object[] oIDList = EntityInstanceIdEncoder.DecodeEntityInstanceId(entityId); id = new Identity(oIDList[0]); // Execute specific finder method and get the entity instance entInstance = entity.FindSpecific(id, methodInstance.Name, entity.GetLobSystem().GetLobSystemInstances()[0].Value); item[dataField.RelatedField] = entityId.ToString(); } else { object oID = GetTypedIDValue(entityId, entity); id = new Identity(oID); string encodedIdentifier = EntityInstanceIdEncoder.EncodeEntityInstanceId(new object[] { oID }); // Execute specific finder method and get the entity instance entInstance = entity.FindSpecific(id, methodInstance.Name, entity.GetLobSystem().GetLobSystemInstances()[0].Value); item[dataField.RelatedField] = encodedIdentifier; } } } } catch (ObjectNotFoundException notFoundException) { LogError("GetEntityInstance errored with message " + notFoundException.Message + ". Adding item to Guidewire."); Console.WriteLine("GetEntityInstance errored with message " + notFoundException.Message + ". Adding item to Guidewire."); bool addDocumentToGuidewire = CallGuidewire(item, GuidewireOperationType.New); string outMessage = ""; if (addDocumentToGuidewire) { outMessage = string.Format("Item with ID {0} added to Guidewire", item.ID); } else { outMessage = string.Format("Item with ID {0} could not be added to Guidewire", item.ID); if (Settings.Default.DeleteFailures) { try { // Recycle the item if it can't be added to guidewire and it's older than 30 days if (DateTime.Now.AddDays(-30) > (DateTime)item[SPBuiltInFieldId.Modified]) { item.Recycle(); } } catch { // Swallow this error. The item doesn't exist in Guidewire and can't be deleted in SharePoint. It has problems } } LogError(outMessage); } Console.WriteLine(outMessage); } catch (Exception ex) { // Swallow this error LogError("GetEntityInstance errored with message " + ex.Message); Console.WriteLine("GetEntityInstance errored with message " + ex.Message); } return(entInstance); }
protected void UpdateCustomer_Click(object sender, EventArgs e) { // Make sure we have values for the entity namespace and name. if (!EntityValuesAreSet) { DisplaySetPropertyValuePrompt(true); return; } else { DisplaySetPropertyValuePrompt(false); } // Do simple validation of the customer ID. Make sure it is // an integer. int customerID = -1; if (!ValidateCustomerID(CustomerID.Text, ref customerID)) { StatusLabel.ForeColor = Color.Red; StatusLabel.Text = "Please enter an integer for the Customer ID value."; return; } try { using (new Microsoft.SharePoint.SPServiceContextScope( SPServiceContext.GetContext(SPContext.Current.Site))) { // Get the BDC service and metadata catalog. BdcService service = SPFarm.Local.Services.GetValue <BdcService>(String.Empty); IMetadataCatalog catalog = service.GetDatabaseBackedMetadataCatalog( SPServiceContext.Current); // Get the entity using the specified name and namespace. IEntity entity = catalog.GetEntity(EntityNamespace, EntityName); ILobSystemInstance LobSysteminstance = entity.GetLobSystem().GetLobSystemInstances()[0].Value; // Create an Identity based on the specified Customer ID. Identity identity = new Identity(customerID); // Get a method instance for the Updater method. IMethodInstance method = entity.GetMethodInstance("UpdateCustomer", MethodInstanceType.Updater); // The UpdateCustomer method of the external content type // maps to the UpdateCustomer method in the AdventureWorks // web service. Looking at the source for the web service // shows that the UpdateCustomer method has the following // signature: // // public void UpdateCustomer(SalesCustomer customer) // // The SalesCustomer type has the following layout: // // public class SalesCustomer // { // public int CustomerId { get; set; } // public String Title { get; set; } // public String FirstName { get; set; } // public String MiddleName { get; set; } // public String LastName { get; set; } // public String EmailAddress { get; set; } // public String Phone { get; set; } // public DateTime ModifiedDate { get; set; } // } // Get the collection of parameters for the method. // In this case there is only one. IParameterCollection parameters = method.GetMethod().GetParameters(); // Use type reflection to get an instance of a // SalesCustomer object to pass as a parameter. ITypeReflector reflector = parameters[0].TypeReflector; ITypeDescriptor rootTypeDescriptor = parameters[0].GetRootTypeDescriptor(); object[] methodParamInstances = method.GetMethod().CreateDefaultParameterInstances( method); Object instance = methodParamInstances[0]; // Get type descriptors for each of the SalesCustomer // members. ITypeDescriptor customerIDTypeDescriptor = rootTypeDescriptor.GetChildTypeDescriptors()[0]; ITypeDescriptor titleTypeDescriptor = rootTypeDescriptor.GetChildTypeDescriptors()[1]; ITypeDescriptor firstNameTypeDescriptor = rootTypeDescriptor.GetChildTypeDescriptors()[2]; ITypeDescriptor middleNameTypeDescriptor = rootTypeDescriptor.GetChildTypeDescriptors()[3]; ITypeDescriptor lastNameTypeDescriptor = rootTypeDescriptor.GetChildTypeDescriptors()[4]; ITypeDescriptor emailAddressTypeDescriptor = rootTypeDescriptor.GetChildTypeDescriptors()[5]; ITypeDescriptor phoneTypeDescriptor = rootTypeDescriptor.GetChildTypeDescriptors()[6]; ITypeDescriptor modifiedDateTypeDescriptor = rootTypeDescriptor.GetChildTypeDescriptors()[7]; // Set the values of the SalesCustomer object members // with the values specified by the user. reflector.Set(customerIDTypeDescriptor, rootTypeDescriptor, ref instance, customerID); reflector.Set(titleTypeDescriptor, rootTypeDescriptor, ref instance, Title.Text); reflector.Set(firstNameTypeDescriptor, rootTypeDescriptor, ref instance, FirstName.Text); reflector.Set(middleNameTypeDescriptor, rootTypeDescriptor, ref instance, MiddleName.Text); reflector.Set(lastNameTypeDescriptor, rootTypeDescriptor, ref instance, LastName.Text); reflector.Set(emailAddressTypeDescriptor, rootTypeDescriptor, ref instance, Email.Text); reflector.Set(phoneTypeDescriptor, rootTypeDescriptor, ref instance, Phone.Text); reflector.Set(modifiedDateTypeDescriptor, rootTypeDescriptor, ref instance, DateTime.Now); // Execute the updater method, passing the parameter. entity.Execute(method, LobSysteminstance, ref methodParamInstances); StatusLabel.ForeColor = Color.Green; StatusLabel.Text = "Customer successfully updated."; } } catch (Exception ex) { StatusLabel.ForeColor = Color.Red; StatusLabel.Text = "Unable to find customer with ID = " + CustomerID.Text + ". " + ex.Message; } }
protected void FindCustomerByID_Click( object sender, EventArgs e) { // Make sure we have values for the entity namespace and name. if (!EntityValuesAreSet) { DisplaySetPropertyValuePrompt(true); return; } else { DisplaySetPropertyValuePrompt(false); } // Do simple validation of the customer ID. Make sure it is // an integer. int customerID = -1; if (!ValidateCustomerID(CustomerID.Text, ref customerID)) { ClearFields(false); StatusLabel.ForeColor = Color.Red; StatusLabel.Text = "Please enter an integer for the Customer ID value."; return; } try { using (new Microsoft.SharePoint.SPServiceContextScope( SPServiceContext.GetContext(SPContext.Current.Site))) { // Get the BDC service and metadata catalog. BdcService service = SPFarm.Local.Services.GetValue <BdcService>(String.Empty); IMetadataCatalog catalog = service.GetDatabaseBackedMetadataCatalog( SPServiceContext.Current); // Get the entity using the specified name and namespace. IEntity entity = catalog.GetEntity(EntityNamespace, EntityName); ILobSystemInstance LobSysteminstance = entity.GetLobSystem().GetLobSystemInstances()[0].Value; // Create an Identity based on the specified Customer ID. Identity identity = new Identity(customerID); // Get a method instance for the SpecificFinder method. IMethodInstance method = entity.GetMethodInstance("GetCustomerById", MethodInstanceType.SpecificFinder); // Execute the Specific Finder method to return the // customer data. IEntityInstance iei = entity.FindSpecific(identity, LobSysteminstance); // Display the data for the returned customer in the UI. Title.Text = iei["Title"] != null ? iei["Title"].ToString() : string.Empty; FirstName.Text = iei["FirstName"] != null ? iei["FirstName"].ToString() : string.Empty; MiddleName.Text = iei["MiddleName"] != null ? iei["MiddleName"].ToString() : string.Empty; LastName.Text = iei["LastName"] != null ? iei["LastName"].ToString() : string.Empty; Email.Text = iei["EmailAddress"] != null ? iei["EmailAddress"].ToString() : string.Empty; Phone.Text = iei["Phone"] != null ? iei["Phone"].ToString() : string.Empty; } } catch (Exception ex) { ClearFields(false); StatusLabel.ForeColor = Color.Red; StatusLabel.Text = "Unable to find customer with ID = " + CustomerID.Text + ". " + ex.Message; } }
public void ExecuteStatic(IMethodInstance methodInstance, ILobSystemInstance lobSystemInstance, object[] methodSignatureArgs, IExecutionContext context) { if (methodInstance == null) { throw (new ArgumentNullException("methodInstance")); } if (lobSystemInstance == null) { throw (new ArgumentNullException("lobSystemInstance")); } if (methodSignatureArgs == null) { throw (new ArgumentNullException("args")); } #region validate the base folder object baseFolderValue; if (!lobSystemInstance.GetProperties().TryGetValue(baseFolderPropertyName, out baseFolderValue)) { throw new InvalidOperationException("BaseFolder property is missing"); } String baseFolderName = baseFolderValue as string; if (String.IsNullOrEmpty(baseFolderName)) { throw new InvalidOperationException("BaseFolder proeprty contains an invalid value."); } DirectoryInfo baseFolder = new DirectoryInfo(baseFolderName); if (!baseFolder.Exists) { throw new InvalidOperationException("Base folder doesn't exist."); } #endregion //This connector works based on the type of the MethodInstance //Most other connectors work on the name of the method if (methodInstance.MethodInstanceType == MethodInstanceType.Finder) { //Connector assumption: //First parameter will always be a wildcarded search string for file name //Second parameter will always be the return value String wildcard = methodSignatureArgs[0] as string; IList <FileInfo> results = new List <FileInfo>(); methodSignatureArgs[1] = baseFolder.GetFiles(wildcard); } else if (methodInstance.MethodInstanceType == MethodInstanceType.SpecificFinder) { //Connector assumption: //First parameter will always be the file name //Second parameter will always be the return value string fileName = methodSignatureArgs[0] as string; FileInfo result = new FileInfo(Path.Combine(baseFolder.FullName, fileName)); if (result.Exists && result.Directory.FullName.Equals(baseFolder.FullName)) { methodSignatureArgs[1] = result; } } else if (methodInstance.MethodInstanceType == MethodInstanceType.StreamAccessor) { //Connector assumption: //First parameter will always be the file name //Second parameter will always be the return value string fileName = methodSignatureArgs[0] as string; FileInfo result = new FileInfo(Path.Combine(baseFolder.FullName, fileName)); if (result.Exists && result.Directory.FullName.Equals(baseFolder.FullName)) { methodSignatureArgs[1] = result.OpenRead(); } } }