Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public SearchResults ExecuteView(Guid viewId, EntityReference parentEntity, string searchString, int page, int pageSize)
- {
- var view = CRMCache.SavedQueries[viewId];
- var metadata = CRMCache.EntityMetadata[view.ReturnedTypeCode];
- var primaryAttributeName = metadata.PrimaryNameAttribute;
- var primaryIdAttributeName = metadata.PrimaryIdAttribute;
- var requiredFields = new string[] { };
- if (metadata.LogicalName != "systemuser")
- {
- requiredFields = new string[] { primaryAttributeName, primaryIdAttributeName, "statecode", "statuscode" };
- }
- // build list of attributes to be returned
- // include the first 3 (specified in LayoutXml) from the view and add the required
- var layoutXml = XElement.Parse(view.LayoutXml);
- var viewAttributes = layoutXml
- .Element("row")
- .Elements("cell")
- .Select(e => (string)e.Attribute("name"))
- .ToList();
- var addAttributes = viewAttributes.Take(3).Union(requiredFields);
- var viewXml = XElement.Parse(view.FetchXml);
- var viewEntityNode = viewXml.Element("entity");
- viewEntityNode.Descendants("attribute").Remove();
- viewEntityNode.Add(addAttributes.Select(s => new XElement("attribute", new XAttribute("name", s))));
- // add quicksearch filter
- if (string.IsNullOrWhiteSpace(searchString) == false)
- {
- var quickSearch = CRMCache.SavedQueries.FirstOrDefault(q => q.ReturnedTypeCode == view.ReturnedTypeCode && q.QueryType == SavedQueryQueryType.QuickFindSearch);
- if (quickSearch != null)
- {
- var quickSearchXml = XElement.Parse(quickSearch.FetchXml);
- var quickSearchFilter = quickSearchXml.XPathSelectElement("//filter[@isquickfindfields=1]");
- foreach (var condition in quickSearchFilter.Elements("condition"))
- {
- condition.SetAttributeValue("value", string.Format(condition.Attribute("value").Value, "%" + searchString + "%"));
- }
- viewEntityNode.Add(quickSearchFilter);
- }
- }
- // "associated view"
- // find entities related to the parent entity specified
- // get the attribute name that references the parent entity from relationships
- if(parentEntity != null)
- {
- var fkName = from r in metadata.ManyToOneRelationships
- where r.ReferencedEntity == parentEntity.LogicalName
- && r.CascadeConfiguration.Delete.Value != CascadeType.NoCascade
- && r.CascadeConfiguration.Delete.Value != CascadeType.RemoveLink
- && r.CascadeConfiguration.Reparent.Value != CascadeType.NoCascade
- && r.CascadeConfiguration.Share.Value != CascadeType.NoCascade
- && r.CascadeConfiguration.Unshare.Value != CascadeType.NoCascade
- select r.ReferencingAttribute;
- viewEntityNode.Add(
- new XElement("filter"
- , new XAttribute("type", "and")
- , new XElement("condition"
- , new XAttribute("attribute", fkName.First())
- , new XAttribute("operator", "eq")
- , new XAttribute("value", parentEntity.Id.ToString())
- )
- )
- );
- }
- viewXml.Add(new XAttribute("page", page)
- , new XAttribute("count", pageSize)
- , new XAttribute("returntotalrecordcount", "true"));
- var result = Proxy.RetrieveMultiple(new FetchExpression(viewXml.ToString(SaveOptions.DisableFormatting)));
- var entities = from e in result.Entities
- let atts = from a in e.Attributes
- join m in metadata.Attributes on a.Key equals m.LogicalName //eam.Value on a.Key equals m.LogicalName
- select new EntityAttribute
- {
- Metadata = m,
- Value = a.Value,
- FormattedValue = e.FormattedValues.Contains(a.Key) ? e.FormattedValues[a.Key] : null,
- }
- select new EntityInfo
- {
- Attributes = new EntityAttributeCollection(atts),
- Entity = new EntityReference { Id = e.Id, LogicalName = e.LogicalName, Name = e.GetAttributeValue<string>(primaryAttributeName) },
- Metadata = CRMCache.EntityMetadata[e.LogicalName],
- };
- // the TotalRecordCount property will not go above 5000, so we need to do a 2nd query to get the correct count
- // aggregate queries cannot contain non-aggregate attribute or order tags
- viewEntityNode.Descendants("attribute").Remove();
- viewEntityNode.Descendants("order").Remove();
- viewEntityNode.Add(new XElement("attribute", new XAttribute("name", primaryIdAttributeName), new XAttribute("aggregate", "count"), new XAttribute("alias", "count")));
- viewXml.SetAttributeValue("aggregate", "true");
- viewXml.SetAttributeValue("page", null);
- viewXml.SetAttributeValue("count", null);
- viewXml.SetAttributeValue("returntotalrecordcount", null);
- viewXml.SetAttributeValue("distinct", "false");
- int totalRecordCount = 50000; // AggregateQueryRecordLimit = 50k, if exception thrown, return 50k and display as 50000+
- try
- {
- var countResult = Proxy.RetrieveMultiple(new FetchExpression(viewXml.ToString(SaveOptions.DisableFormatting)));
- totalRecordCount = (int)((AliasedValue)countResult.Entities[0].Attributes["count"]).Value;
- }
- catch (System.ServiceModel.FaultException<OrganizationServiceFault> ex)
- {
- if (ex.Message != "AggregateQueryRecordLimit exceeded. Cannot perform this operation.")
- {
- throw;
- }
- }
- var searchResults = new SearchResults
- {
- Page = page,
- PageSize = pageSize,
- Entities = entities,
- TotalRecordCount = totalRecordCount
- };
- return searchResults;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement