protected override void Execute(CodeActivityContext executionContext) { IWorkflowContext context = executionContext.GetExtension <IWorkflowContext>(); IOrganizationServiceFactory serviceFactory = executionContext.GetExtension <IOrganizationServiceFactory>(); IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId); string fetchXMLQuery = FetchXML.Get(executionContext); EntityCollection recordsToProcess = service.RetrieveMultiple(new FetchExpression(fetchXMLQuery)); EntityReference processEntityReference = WorkflowToExecute.Get(executionContext); foreach (var entity in recordsToProcess.Entities) { try { var request = new ExecuteWorkflowRequest { EntityId = entity.Id, WorkflowId = processEntityReference.Id }; service.Execute(request); } catch (Exception ex) { throw new Exception($"Error executing workflow on {entity.Id}: {ex.Message}", ex); } } }
// fetchXml version for getting ordered products private string GetOderDetails(Guid orderID) { var xml = new FetchXML(ENTITY); FetchElement entity = xml.EntityElement; entity.AddFilter() .AddCondition("salesorderid", "eq", orderID.ToString()); entity.AddLinkEntity("product", "productid", "productid").AddField("name", "product"); return(xml.ToQueryString()); }
public void CanAddFragment() { const string result = @"<fetch version='1.0' mapping='logical'><entity name='test'><link-entity name='test' /></entity></fetch>"; XmlDocument doc = new XmlDocument(); doc.LoadXml(result); var xml = new FetchXML("test"); FetchElement frgment = new FetchElement("link-entity", "test"); xml.EntityElement.AddFragment(frgment); Assert.Equal("?fetchXml=" + doc.OuterXml, xml.ToQueryString()); }
/// <summary> /// Build a query to get a list of child accounts of an account defined by its name /// </summary> /// <param name="parent"></param> /// <returns>The result from Dynamics server as string</returns> private string ListChildAccountsQuery(string parent) { var xml = new FetchXML(ENTITY); FetchElement entity = xml.EntityElement; entity.AddField("name"); entity.AddField("accountid"); FetchElement linkedEntiry = entity.AddLinkEntity("account", "accountid", "parentaccountid"); FetchElement filter = linkedEntiry.AddFilter(); filter.AddCondition("name", "eq", value: parent); return(xml.ToQueryString()); }
public void CanProduceXml() { const string result = @"<fetch version='1.0' mapping='logical'><entity name='test'><attribute name='name' /><attribute name='description' /></entity></fetch>"; XmlDocument doc = new XmlDocument(); doc.LoadXml(result); var xml = new FetchXML("test"); FetchElement entity = xml.EntityElement; entity.AddField("name") .AddField("description"); Assert.Equal("?fetchXml=" + doc.OuterXml, xml.ToQueryString()); }
/// <summary> /// Query to get orders of a contact by its ID /// </summary> /// <param name="contactID"></param> /// <returns></returns> private string GetOrdersOfQuery(Guid contactID) { /* * <fetch version="1.0" mapping="logical"> * <entity name="salesorder"> * <attribute name="name" /> * <attribute name="description" /> * <attribute name="new_orderid" /> * <link-entity name="connection" from="record1id" to="salesorderid"> * <filter type="and"> * <condition attribute="record1objecttypecode" operator="eq" value="1088" /> * <condition attribute="record2objecttypecode" operator="eq" value="2" /> * </filter> * <link-entity name="connectionrole" from="connectionroleid" to="record2roleid"> * <attribute name="name" alias="role" /> * </link-entity> * <link-entity name="contact" from="contactid" to="record2id"> * <filter type="and"> * <condition attribute="contactid" operator="eq" value="12ed419f-5863-e611-80e3-c4346bc516e8" /> * </filter> * </link-entity> * </link-entity> * </entity> * </fetch> */ var xml = new FetchXML(ENTITY); FetchElement entity = xml.EntityElement; entity.AddField("name") .AddField("description") .AddField("new_orderid"); FetchElement linkedConnection = entity.AddLinkEntity("connection", "record1id", "salesorderid"); FetchElement connectionFilter = linkedConnection.AddFilter(); connectionFilter.AddCondition("record1objecttypecode", "eq", "1088") .AddCondition("record2objecttypecode", "eq", "2"); linkedConnection.AddLinkEntity("connectionrole", "connectionroleid", "record2roleid") .AddField("name", "role"); FetchElement linkedContact = linkedConnection.AddLinkEntity("contact", "contactid", "record2id"); FetchElement contactFilter = linkedContact.AddFilter(); contactFilter.AddCondition("contactid", "eq", contactID.ToString()); return(xml.ToQueryString()); }
private static void AddRelationFilter(IExecutionContainer container, ShuffleBlocks blocks, DataBlockRelation relation, XmlNode xEntity) { if (blocks != null && blocks.Count > 0) { var block = relation.Block; var attribute = relation.Attribute; var pkattribute = relation.PKAttribute; var includenull = relation.IncludeNull; var ids = new List <string>(); var parentcoll = blocks.ContainsKey(block) ? blocks[block] : null; if (parentcoll != null && parentcoll.Entities.Count > 0) { foreach (var parent in parentcoll.Entities) { if (string.IsNullOrEmpty(pkattribute)) { ids.Add(parent.Id.ToString()); } else { ids.Add(parent.GetAttribute(pkattribute, new EntityReference()).Id.ToString()); } } } else { // Adding temp guid to indicate "no matches", as ConditionOperator.In will fail if no values are given ids.Add(new Guid().ToString()); } if (!includenull) { FetchXML.AppendFilter(xEntity, "and", attribute, "in", ids.ToArray()); } else { var xFilter = FetchXML.AppendFilter(xEntity, "or"); FetchXML.AppendCondition(xFilter, attribute, "null"); FetchXML.AppendCondition(xFilter, attribute, "in", ids.ToArray()); } container.Log($"Adding relation condition for {attribute} in {ids.Count} values in {block}.{pkattribute}"); } }
private EntityCollection ExportDataBlock(IExecutionContainer container, ShuffleBlocks blocks, DataBlock block) { container.StartSection("ExportDataBlock"); container.Log($"Block: {block.Name}"); EntityCollection cExportEntities = null; if (block.Export != null) { #region Define attributes var attributes = block.Export.Items.Where(i => i is DataBlockExportAttributes).FirstOrDefault() as DataBlockExportAttributes; var allcolumns = false; var lAttributes = new List <string>(); var lNullAttributes = new List <string>(); if (attributes != null) { foreach (var attribute in attributes.Attribute) { var attr = attribute.Name; container.Log($"Adding column: {attr}"); lAttributes.Add(attr.Replace("*", "%")); if (attr.Contains("*")) { allcolumns = true; container.Log("Found wildcard"); } else { if (attribute.IncludeNull) { lNullAttributes.Add(attr); } } } } else { allcolumns = true; lAttributes.Add("*"); container.Log("Attributes not specified, retrieving all"); } #endregion Define attributes var fetchxml = block.Export.Items.Where(i => i is string).FirstOrDefault() as string; if (!string.IsNullOrWhiteSpace(fetchxml)) { container.StartSection("Export entity using FetchXML"); #if DEBUG container.Log($"FetchXML:\n{fetchxml}"); #endif cExportEntities = container.RetrieveMultiple(new FetchExpression(fetchxml)); container.EndSection(); } else if (!block.TypeSpecified || block.Type == EntityTypes.Entity) { #region QueryExpression Entity container.StartSection($"Export entity {block.Entity}"); var qExport = new QueryExpression(block.Entity); if (block.Export.ActiveOnly) { Query.AppendConditionActive(qExport.Criteria); //CintQryExp.AppendConditionActive(qExport.Criteria); } if (block.Relation != null) { foreach (var relation in block.Relation) { AddRelationFilter(container, blocks, block.Entity, relation, qExport.Criteria); } } foreach (var filter in block.Export.Items.Where(i => i is DataBlockExportFilter).Cast <DataBlockExportFilter>()) { AddFilter(container, qExport, filter); } foreach (var sort in block.Export.Items.Where(i => i is DataBlockExportSort).Cast <DataBlockExportSort>()) { qExport.AddOrder(sort.Attribute, sort.Type == SortTypes.Desc ? OrderType.Descending : OrderType.Ascending); } if (allcolumns) { qExport.ColumnSet = new ColumnSet(true); } else { foreach (var attr in lAttributes) { qExport.ColumnSet.AddColumn(attr); } } #if DEBUG container.Log("Converting to FetchXML"); try { var fetch = container.ConvertToFetchXml(qExport); container.Log($"Exporting {block.Entity}:\n{fetch}"); } catch (Exception ex) { container.Log("Conversion error:"); container.Log(ex); } #endif cExportEntities = container.RetrieveMultiple(qExport); if (allcolumns) { SelectAttributes(container, cExportEntities, lAttributes, lNullAttributes); } SendLine(container, $"Block {block.Name} - {cExportEntities.Count()} records"); container.EndSection(); #endregion QueryExpression Entity } else if (block.Type == EntityTypes.Intersect) { #region FetchXML Intersect container.StartSection($"Export intersect {block.Entity}"); var xDoc = new XmlDocument(); var xEntity = FetchXML.Create(xDoc, block.Entity); FetchXML.AddAttribute(xEntity, lAttributes.ToArray()); if (block.Relation != null) { foreach (var relation in block.Relation) { AddRelationFilter(container, blocks, relation, xEntity); } } var fetch = xDoc.OuterXml; //Imran: Removed because this is causing invalid Xml errors. Could not see the point of having these placeholders. //fetch = fetch.Replace("<fetch ", "<fetch {0} {1} "); // Detta för att se till att CrmServiceProxy.RetrieveMultiple kan hantera paging #if DEBUG container.Log($"Exporting intersect entity {block.Entity}\n{fetch}"); #endif var qExport = new FetchExpression(fetch); cExportEntities = container.RetrieveMultiple(qExport); foreach (var entity in cExportEntities.Entities) { var newattributes = new List <KeyValuePair <string, object> >(); foreach (var attr in entity.Attributes) { if (attr.Value is Guid guid) { var attrname = attr.Key; var relatedentity = attrname.Substring(0, attrname.Length - (attrname.EndsWith("idone") || attrname.EndsWith("idtwo") ? 5 : 2)); if (!newattributes.Contains(new KeyValuePair <string, object>(attrname, new EntityReference(relatedentity, guid)))) { container.Log($"Adding Attribute {attrname} - Related entity {relatedentity}"); newattributes.Add(new KeyValuePair <string, object>(attrname, new EntityReference(relatedentity, guid))); #if DEBUG container.Log($"{attrname} added"); #endif } else { #if DEBUG container.Log($"{attrname} already exists."); #endif } } } foreach (var newattr in newattributes) { #if DEBUG container.Log($"Entity {entity.LogicalName} contains attribute {newattr.Key}: {entity.Attributes.Contains(newattr.Key)}"); #endif if (!entity.Attributes.Contains(newattr.Key)) { entity.Attributes.Add(newattr.Key, newattr.Value); } } } container.EndSection(); #endregion FetchXML Intersect } container.Log($"Returning {cExportEntities.Count()} records"); } container.EndSection(); return(cExportEntities); }