title: How to lookup entities in EntityFramework 4 by a finder interface? (works in LinqToSql)
body: <p>I have a repository layer which my applications access which can be initialised with an <code>IDataSource</code>; e.g. LinqToSqlDataSource, EntityFrameworkDataSource, etc...</p>
  
  <p>An IDataSource provides methods for inserting, updating, deleting and querying a data source respectively. Relevant to this question, is that the <code>FindAll&lt;T&gt;</code> returns an <code>IQueryable&lt;T&gt;</code>.</p>
  
  <p>All my base entities implement a simple interface to make looking up entities by id generic and convenient;</p>
  
  <pre><code>public interface IAmIdentifiable&lt;T&gt;
  {
      T Id { get; set; }
  }
  </code></pre>
  
  <p>Below is the relevant code for the <code>FindById&lt;T, TKey&gt;</code> method I am having problems with in EntityFramework.</p>
  
  <pre><code>public class Repository
  {
      public Repository(IDataSource dataSource)
      {...}
  
      public T FindById&lt;T, TKey&gt;(TKey identifier) where T : class, IAmIdentifiable&lt;TKey&gt;
      {
          return _DataSource.FindAll&lt;T&gt;().SingleOrDefault(i =&gt; i.Id.Equals(identifier));
      }
  
      ...
  }
  </code></pre>
  
  <p>This <code>FindById&lt;T, Tkey&gt;(...)</code> <strong>works fine with LinqToSql but does not work in EntityFramework 4</strong>.</p>
  
  <p><strong>Example usage</strong></p>
  
  <pre><code>User user = Repository.FindById&lt;User, int&gt;(someUserId);
  Message msg = Repository.FindById&lt;Message, Guid&gt;(someMessageId);
  </code></pre>
  
  <p>When the above code is run with an EntityFramework 4 IDataSource implementation it produces the following error;</p>
  
  <p><strong>Unable to create a constant value of type 'System.Object'. Only primitive types ('such as Int32, String, and Guid') are supported in this context.</strong></p>
  
  <p>I have tried changing this to perform an == comparison on value types. I read that a roundabout way to constrain a generic to a value type is to constraint to <code>struct</code>. I have updated the base interface for all entities and the repository finder accordingly...</p>
  
  <pre><code>public interface IAmIdentifiable&lt;T&gt; where T : struct
  {
      T Id { get; set; }
  }
  
  public T FindById&lt;T, TKey&gt;(TKey identifier)
      where T : class, IAmIdentifiable&lt;TKey&gt;
      where TKey : struct
  {
      return _DataSource.FindAll&lt;T&gt;().SingleOrDefault(i =&gt; i.Id == identifier);
  }
  </code></pre>
  
  <p>However this still results in a compilation error;</p>
  
  <p><strong>Error 59 Operator '==' cannot be applied to operands of type 'TKey' and 'TKey'</strong></p>
  
  <p>Can anybody shed some light on how I might go about casting these entities to the <code>IAmIdentifiable&lt;T&gt;</code> interface in order to have a generic way to retrieve entities by Id?</p>