title: CRM FetchXml, how can I dynamically add quicksearch filter that will match related entity's name?
body: <p>I have a web page outside of CRM that allows users to perform CRM lookups. I need to implement filtering the lookup results using quick search like in the normal CRM UI.</p>
  
  <p>I get the FetchXML for the selected entity/view, then get the FetchXML for the selected entity's quick search view, extract the filter node where isquickfindfields=1, replace {0} with what they typed into the search box, insert the modified node into the selected view's FetchXML, and execute it.</p>
  
  <p>The problem that I'm running into is some of the quick search filters are against a related entity's id field, but the match needs to go against that entity's primary name attribute.</p>
  
  <p>For example, here's the quick search for the account entity:</p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;fetch version="1.0" output-format="xml-platform" mapping="logical"&gt;
  &lt;entity name="account"&gt;
      &lt;attribute name="name" /&gt;
      &lt;attribute name="primarycontactid" /&gt;
      &lt;attribute name="address1_city" /&gt;
      &lt;attribute name="telephone1" /&gt;
      &lt;attribute name="emailaddress1" /&gt;
      &lt;order attribute="name" descending="false" /&gt;
      &lt;filter type="and"&gt;
          &lt;condition attribute="statecode" operator="eq" value="0" /&gt;
      &lt;/filter&gt;
      &lt;filter type="or" isquickfindfields="1"&gt;
          &lt;condition attribute="primarycontactid" operator="like" value="{0}" /&gt;
          &lt;condition attribute="telephone1" operator="like" value="{0}" /&gt;
          &lt;condition attribute="emailaddress1" operator="like" value="{0}" /&gt;
          &lt;condition attribute="accountnumber" operator="like" value="{0}" /&gt;
          &lt;condition attribute="name" operator="like" value="{0}" /&gt;
      &lt;/filter&gt;
      &lt;attribute name="accountid" /&gt;
  &lt;/entity&gt;
  </code></pre>
  
  <p></p>
  
  <p>And when I plug in the search text and execute the view, I get this error from RetrieveMultiple:</p>
  
  <pre><code>An exception System.FormatException was thrown while trying to convert input value '%acme%' to attribute 'account.primarycontactid'. Expected type of attribute value: System.Guid. Exception raised: Guid should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).
  </code></pre>
  
  <p>If I use the normal CRM interface, do a lookup against accounts and type in the name of a contact in the quick search box, the search works as expected (lists accounts where name of the primary contact is what I entered). Because of this, I had assumed that when CRM queries the database, it would "intelligently" match non-Guid strings againt an entity reference's primary name attribute.</p>
  
  <p>Here's the block of code (<a href="http://pastebin.com/RN35VLbe" rel="nofollow">pastebin</a> of entire method) that adds the quicksearch filter:</p>
  
  <pre class="lang-cs prettyprint-override"><code>if (string.IsNullOrWhiteSpace(searchString) == false)
  {
      var quickSearch = CRMCache.SavedQueries.FirstOrDefault(q =&gt; q.ReturnedTypeCode == view.ReturnedTypeCode &amp;&amp; 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);
      }
  }
  </code></pre>
  
  <p>While I'm curious how the normal CRM UI handles this, my question is how do I dynamically apply quick search filtering on lookups/views that will correctly filter against a related entity's primary name attribute?</p>
  
  <hr>
  
  <p><strong>[Edit for clarification]</strong></p>
  
  <p><em>Quick Search</em> (or <em>Quick Find</em>) is one of the view types in CRM. It defines what attributes are searched when a user enters text into the quick search box or when filtering a lookup. All entities have a <em>quick search</em> view and an entity can have only one.</p>
  
  <p>The requirement to match a related entity's name comes from the <em>quick search</em> view. Not all of them include a filter on an entity reference, but when it does, I need to match against the name and not the guid. Since the normal CRM UI correctly applies the search string against the related entity's name, even though the <em>quick search</em> view's FetchXML has the filter against the id, I had thought CRM handled that case internally. Obviously, that's not the case (the error I got shows this). So I need to detect this case and do something different and I want to do this dynamically.</p>
  
  <p>By dynamically, I mean my code doesn't have a bunch of pre-defined FetchXML strings; it's not coded for specific entities, views or search requirements; and it doesn't need to be modified every time a new entity or view is added or altered. Maybe "dynamic" isn't a good term in this context, but I don't know what else to call it. Entity/view-agnostic?</p>
  
  <p>I don't want code like this:</p>
  
  <pre class="lang-cs prettyprint-override"><code>SearchResults ExecuteView(string entityLogicalName, string searchString)
  {
      switch(entityLogicalName)
      {
          case "account":
              return searchAccounts(searchString);
  
          ... all other enties ...
  
          default:
              throw new Exception("Unknown entity type: " + entityLogicalName);
      }
  }
  
  
  SearchResults searchAccounts(searchString)
  {
      var fetchXml = string.Format(@"
  &lt;fetch&gt;
        &lt;entity name=""account""&gt;
          &lt;link-entity name=""contact"" from=""contactid"" to=""primarycontactid""&gt;
              &lt;attribute name=""name"" alias=""name"" /&gt;
              &lt;filter type=""and""&gt;
                  &lt;condition attribute=""name"" operator=""like"" value=""%{0}%"" /&gt;
              &lt;/filter&gt;
          &lt;/link-entity&gt;
        &lt;/entity&gt;
  &lt;/fetch&gt;", searchString);
  
      return executeSearch(fetchXml);
  }
  </code></pre>
  
  <p>because changes in CRM (add/remove entities, add/remove/update views) would require the code to be updated to match.</p>