Advertisement
Guest User

Untitled

a guest
Mar 13th, 2013
284
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.11 KB | None | 0 0
  1. public SearchResults ExecuteView(Guid viewId, EntityReference parentEntity, string searchString, int page, int pageSize)
  2. {
  3.     var view = CRMCache.SavedQueries[viewId];
  4.     var metadata = CRMCache.EntityMetadata[view.ReturnedTypeCode];
  5.     var primaryAttributeName = metadata.PrimaryNameAttribute;
  6.     var primaryIdAttributeName = metadata.PrimaryIdAttribute;
  7.  
  8.     var requiredFields = new string[] { };
  9.     if (metadata.LogicalName != "systemuser")
  10.     {
  11.         requiredFields = new string[] { primaryAttributeName, primaryIdAttributeName, "statecode", "statuscode" };
  12.     }
  13.  
  14.     // build list of attributes to be returned
  15.     // include the first 3 (specified in LayoutXml) from the view and add the required
  16.     var layoutXml = XElement.Parse(view.LayoutXml);
  17.     var viewAttributes = layoutXml
  18.                             .Element("row")
  19.                             .Elements("cell")
  20.                             .Select(e => (string)e.Attribute("name"))
  21.                             .ToList();
  22.    
  23.     var addAttributes = viewAttributes.Take(3).Union(requiredFields);
  24.  
  25.  
  26.     var viewXml = XElement.Parse(view.FetchXml);
  27.     var viewEntityNode = viewXml.Element("entity");
  28.    
  29.     viewEntityNode.Descendants("attribute").Remove();
  30.     viewEntityNode.Add(addAttributes.Select(s => new XElement("attribute", new XAttribute("name", s))));
  31.  
  32.     // add quicksearch filter
  33.     if (string.IsNullOrWhiteSpace(searchString) == false)
  34.     {
  35.         var quickSearch = CRMCache.SavedQueries.FirstOrDefault(q => q.ReturnedTypeCode == view.ReturnedTypeCode && q.QueryType == SavedQueryQueryType.QuickFindSearch);
  36.         if (quickSearch != null)
  37.         {
  38.             var quickSearchXml = XElement.Parse(quickSearch.FetchXml);
  39.             var quickSearchFilter = quickSearchXml.XPathSelectElement("//filter[@isquickfindfields=1]");
  40.             foreach (var condition in quickSearchFilter.Elements("condition"))
  41.             {
  42.                 condition.SetAttributeValue("value", string.Format(condition.Attribute("value").Value, "%" + searchString + "%"));
  43.             }
  44.  
  45.             viewEntityNode.Add(quickSearchFilter);
  46.         }
  47.     }
  48.  
  49.     // "associated view"
  50.     // find entities related to the parent entity specified
  51.     // get the attribute name that references the parent entity from relationships
  52.     if(parentEntity != null)
  53.     {
  54.         var fkName = from r in metadata.ManyToOneRelationships
  55.                      where r.ReferencedEntity == parentEntity.LogicalName
  56.                         && r.CascadeConfiguration.Delete.Value != CascadeType.NoCascade
  57.                         && r.CascadeConfiguration.Delete.Value != CascadeType.RemoveLink
  58.                         && r.CascadeConfiguration.Reparent.Value != CascadeType.NoCascade
  59.                         && r.CascadeConfiguration.Share.Value != CascadeType.NoCascade
  60.                         && r.CascadeConfiguration.Unshare.Value != CascadeType.NoCascade
  61.                      select r.ReferencingAttribute;
  62.  
  63.        
  64.         viewEntityNode.Add(
  65.             new XElement("filter"
  66.                 , new XAttribute("type", "and")
  67.                 , new XElement("condition"
  68.                     , new XAttribute("attribute", fkName.First())
  69.                     , new XAttribute("operator", "eq")
  70.                     , new XAttribute("value", parentEntity.Id.ToString())
  71.                 )
  72.             )
  73.         );
  74.     }
  75.  
  76.     viewXml.Add(new XAttribute("page", page)
  77.           , new XAttribute("count", pageSize)
  78.           , new XAttribute("returntotalrecordcount", "true"));
  79.  
  80.     var result = Proxy.RetrieveMultiple(new FetchExpression(viewXml.ToString(SaveOptions.DisableFormatting)));
  81.  
  82.     var entities = from e in result.Entities
  83.  
  84.                     let atts = from a in e.Attributes
  85.                               join m in metadata.Attributes on a.Key equals m.LogicalName //eam.Value on a.Key equals m.LogicalName
  86.                               select new EntityAttribute
  87.                               {
  88.                                   Metadata = m,
  89.                                   Value = a.Value,
  90.                                   FormattedValue = e.FormattedValues.Contains(a.Key) ? e.FormattedValues[a.Key] : null,
  91.                               }
  92.  
  93.                    select new EntityInfo
  94.                    {
  95.                        Attributes = new EntityAttributeCollection(atts),
  96.                        Entity = new EntityReference { Id = e.Id, LogicalName = e.LogicalName, Name = e.GetAttributeValue<string>(primaryAttributeName) },
  97.                        Metadata = CRMCache.EntityMetadata[e.LogicalName],
  98.                    };
  99.  
  100.  
  101.  
  102.     // the TotalRecordCount property will not go above 5000, so we need to do a 2nd query to get the correct count
  103.     // aggregate queries cannot contain non-aggregate attribute or order tags
  104.     viewEntityNode.Descendants("attribute").Remove();
  105.     viewEntityNode.Descendants("order").Remove();
  106.     viewEntityNode.Add(new XElement("attribute", new XAttribute("name", primaryIdAttributeName), new XAttribute("aggregate", "count"), new XAttribute("alias", "count")));
  107.     viewXml.SetAttributeValue("aggregate", "true");
  108.     viewXml.SetAttributeValue("page", null);
  109.     viewXml.SetAttributeValue("count", null);
  110.     viewXml.SetAttributeValue("returntotalrecordcount", null);
  111.     viewXml.SetAttributeValue("distinct", "false");
  112.  
  113.     int totalRecordCount = 50000; // AggregateQueryRecordLimit = 50k, if exception thrown, return 50k and display as 50000+
  114.     try
  115.     {
  116.         var countResult = Proxy.RetrieveMultiple(new FetchExpression(viewXml.ToString(SaveOptions.DisableFormatting)));
  117.         totalRecordCount = (int)((AliasedValue)countResult.Entities[0].Attributes["count"]).Value;
  118.     }
  119.  
  120.     catch (System.ServiceModel.FaultException<OrganizationServiceFault> ex)
  121.     {
  122.         if (ex.Message != "AggregateQueryRecordLimit exceeded. Cannot perform this operation.")
  123.         {
  124.             throw;
  125.         }
  126.     }
  127.  
  128.  
  129.     var searchResults = new SearchResults
  130.     {
  131.         Page = page,
  132.         PageSize = pageSize,
  133.         Entities = entities,
  134.         TotalRecordCount = totalRecordCount
  135.     };
  136.  
  137.     return searchResults;
  138. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement