title: Why does my OData v4 API work for ?$filter=contains, but not ?$filter=field eq 'val'?
body: <p>I've written some OData V4 APIs to pull data from a local SQL database. I'm using curl to query the API. The APIs are ASP.NET and deployed on an IIS server.</p>
  <p>If I query my OData API like this, I get the correct data back:</p>
  <pre><code>IPADDRESS/cdi_unsubscribes?$filter=contains(cdi_email,'info@')
  </code></pre>
  <p>However, if I query my OData with an eq filter like this:</p>
  <pre><code>IPADDRESS/cdi_unsubscribes?$filter=cdi_email eq 'info@email.com'
  </code></pre>
  <p>I get the following error message:</p>
  <blockquote>
  <p>&quot;message&quot;:&quot;The query specified in the URI is not valid. The $filter expression must evaluate to a single boolean value.&quot;</p>
  </blockquote>
  <p>Then curl outputs:</p>
  <blockquote>
  <p>curl: (6) Could not resolve host: eq</p>
  </blockquote>
  <blockquote>
  <p>curl: (6) Could not resolve host: email.com'</p>
  </blockquote>
  <p>I don't understand why this is happening.</p>
  <p>My WebApiConfig:</p>
  <pre><code>public static void Register(HttpConfiguration config)
      {
          ODataModelBuilder builder = new ODataConventionModelBuilder();
  
          config.AddODataQueryFilter();
          config.Select().Expand().Filter().OrderBy().MaxTop(null).Count().SkipToken();
  
          builder.EntitySet&lt;cdi_unsubscribe&gt;(&quot;cdi_unsubscribes&quot;);
          builder.EntityType&lt;cdi_unsubscribe&gt;().Filter(&quot;cdi_email&quot;);
  
          builder.EntitySet&lt;Product&gt;(&quot;Products&quot;);
  
          config.MapODataServiceRoute(&quot;ODataRoute&quot;, null, builder.GetEdmModel());
      }
  </code></pre>
  <p>I've added 2 lines to ensure that filtering works on that specific entity on that field. Removing one doesn't fix this.</p>
  <p>My Controller Class:</p>
  <pre><code>[HttpBasicAuthorize]
  [RequireHttps]
  public class cdi_unsubscribesController : ODataController
  {
      cdi_unsubscribesContext db = new cdi_unsubscribesContext();
  
      private bool cdi_unsubscribeExists(Guid key)
      {
          return db.cdi_unsubscribes.Any(p =&gt; p.id.Equals(key));
      }
  
      protected override void Dispose(bool disposing)
      {
          db.Dispose();
          base.Dispose(disposing);
      }
  
      [EnableQuery]
      public IQueryable&lt;cdi_unsubscribe&gt; Get()
      {
          return db.cdi_unsubscribes;
      }
  
      [EnableQuery]
      public SingleResult&lt;cdi_unsubscribe&gt; Get([FromODataUri] Guid key)
      {
          IQueryable&lt;cdi_unsubscribe&gt; result = db.cdi_unsubscribes.Where(p =&gt; p.id.Equals(key));
          return SingleResult.Create(result);
      }
  </code></pre>
  <p>My Context Class:</p>
  <pre><code>public class cdi_unsubscribesContext : DbContext
  {
      public cdi_unsubscribesContext() : base(&quot;name=cdi_unsubscribesContext&quot;)
      {
  
      }
      public DbSet&lt;cdi_unsubscribe&gt; cdi_unsubscribes { get; set; }
  
      protected override void OnModelCreating(DbModelBuilder modelBuilder)
      {
          modelBuilder.HasDefaultSchema(&quot;crm&quot;);
      }
  }
  </code></pre>
  <p>My Entity Definition:</p>
  <pre><code>public class cdi_unsubscribe
  {
      public Guid id { get; set; }
      public Nullable&lt;int&gt; statecode { get; set; }
      public Nullable&lt;int&gt; statuscode { get; set; }
      public String cdi_email { get; set; }
      public Nullable&lt;Guid&gt; _cdi_contactid_value { get; set; }
      public String cdi_subscriptionchannel { get; set; }
      public Nullable&lt;DateTime&gt; createdon { get; set; }
  }
  </code></pre>
  <p>Am I missing anything obvious? I would have thought that if contains works perfectly, then a basic eq filter should work just fine. My first guess would be that I'm not writing my eq filter correctly, but every example I see online looks just like mine (unless I'm blind!).</p>