title: Is it possible to use IComparable to compare entities in Entity Framework?
body: <p>I have a POCO class that implements <code>IComparable</code>.</p>
  
  <pre><code>public interface IEntity : IComparable
  {
      long Id { get; set; }
  
      Func&lt;IEntity, bool&gt; CompareFunction { get; }
  }
  
  public abstract class BaseEntity : IEntity
  {
      public virtual long Id { get; set; }
  
      public Func&lt;IEntity, bool&gt; CompareFunction
      {
          get
          {
              Func&lt;IEntity, bool&gt; compare = EvaluateEquivalency;
              return compare;
          }
      }
  
      public static int Compare(BaseEntity left, BaseEntity right)
      {
          if (object.ReferenceEquals(left, right))
          {
              return 0;
          }
  
          if (object.ReferenceEquals(left, null))
          {
              return -1;
          }
  
          return left.CompareTo(right);
      }
  
      public static bool operator ==(BaseEntity left, BaseEntity right)
      {
          if (object.ReferenceEquals(left, null))
          {
              return object.ReferenceEquals(right, null);
          }
  
          return left.Equals(right);
      }
  
      public static bool operator !=(BaseEntity left, BaseEntity right)
      {
          return !(left == right);
      }
  
      public static bool operator &lt;(BaseEntity left, BaseEntity right)
      {
          return Compare(left, right) &lt; 0;
      }
  
      public static bool operator &gt;(BaseEntity left, BaseEntity right)
      {
          return Compare(left, right) &gt; 0;
      }
  
      public override bool Equals(object obj)
      {
          IEntity other;
  
          if (!(obj is IEntity)) return false;
  
          other = (IEntity)obj;
  
          if (object.ReferenceEquals(other, null))
          {
              return false;
          }
  
          return this.CompareTo(other) == 0;
      }
  
      public override int GetHashCode()
      {
          return base.GetHashCode();
      }
  
      public virtual int CompareTo(object obj)
      {
          if (obj == null) throw new ArgumentNullException("obj");
          if (!(obj is IEntity)) throw new ArgumentException("obj is not an IEntity");
  
          if (this.Id == ((IEntity)obj).Id) return 0;
  
          return -1;
      }
  
      private bool EvaluateEquivalency(IEntity toCompare)
      {
          return Equals(toCompare);
      }
  }
  </code></pre>
  
  <p>There is <code>DbSet</code> for my POCO class in my <code>DbContext</code>.</p>
  
  <p>However, when I execute <code>BaseRepository.Exists()</code> I get a <code>System.NotSupportedException</code>.</p>
  
  <pre><code>public class BaseRepository&lt;TEntity&gt; : IRepository&lt;TEntity&gt; where TEntity : class, IEntity
  {
      ...
  
      private TEntity Exists(TEntity entity)
      {
          return Context.DbSet&lt;TEntity&gt;.FirstOrDefult(i =&gt; i.CompareTo(entity) == 0);
      }
  
      private TEntity ExistsV2(TEntity entity)
      {
          return Context.DbSet&lt;TEntity&gt;.FirstOrDefult(i =&gt; i.CompareFunction(entity) == 0);
      }
  
      ...
  }
  </code></pre>
  
  <p>The exception stack trace looks like...</p>
  
  <pre><code>System.NotSupportedException was unhandled by user code
    Message=Unable to create a constant value of type '{My POCO Class}'. Only primitive types or enumeration types are supported in this context.
    Source=System.Data.Entity
    StackTrace:
         at System.Data.Objects.ELinq.ExpressionConverter.ConstantTranslator.TypedTranslate(ExpressionConverter parent, ConstantExpression linq)
         at System.Data.Objects.ELinq.ExpressionConverter.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq)
         at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
         at System.Data.Objects.ELinq.ExpressionConverter.EqualsTranslator.TypedTranslate(ExpressionConverter parent, BinaryExpression linq)
         at System.Data.Objects.ELinq.ExpressionConverter.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq)
         at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
         at System.Data.Objects.ELinq.ExpressionConverter.TranslateLambda(LambdaExpression lambda, DbExpression input)
         at System.Data.Objects.ELinq.ExpressionConverter.TranslateLambda(LambdaExpression lambda, DbExpression input, DbExpressionBinding&amp; binding)
         at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, DbExpression&amp; source, DbExpressionBinding&amp; sourceBinding, DbExpression&amp; lambda)
         at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.FirstPredicateTranslatorBase.Translate(ExpressionConverter parent, MethodCallExpression call)
         at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, SequenceMethod sequenceMethod)
         at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq)
         at System.Data.Objects.ELinq.ExpressionConverter.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq)
         at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
         at System.Data.Objects.ELinq.ExpressionConverter.Convert()
         at System.Data.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable`1 forMergeOption)
         at System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
         at System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable&lt;T&gt;.GetEnumerator()
         at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source)
         at System.Data.Objects.ELinq.ObjectQueryProvider.&lt;GetElementFunction&gt;b__1[TResult](IEnumerable`1 sequence)
         at System.Data.Objects.ELinq.ObjectQueryProvider.ExecuteSingle[TResult](IEnumerable`1 query, Expression queryRoot)
         at System.Data.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute[S](Expression expression)
         at System.Data.Entity.Internal.Linq.DbQueryProvider.Execute[TResult](Expression expression)
         at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source, Expression`1 predicate)
  </code></pre>
  
  <p>When I execute <code>BaseRepository.ExistsV2()</code> I get a slightly different <code>System.NotSupportedException</code>.</p>
  
  <pre><code>System.NotSupportedException was unhandled by user code
    HResult=-2146233067
    Message=The LINQ expression node type 'Invoke' is not supported in LINQ to Entities.
    Source=System.Data.Entity
    StackTrace:
         at System.Data.Objects.ELinq.ExpressionConverter.NotSupportedTranslator.Translate(ExpressionConverter parent, Expression linq)
         at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
         at System.Data.Objects.ELinq.ExpressionConverter.TranslateLambda(LambdaExpression lambda, DbExpression input)
         at System.Data.Objects.ELinq.ExpressionConverter.TranslateLambda(LambdaExpression lambda, DbExpression input, DbExpressionBinding&amp; binding)
         at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, DbExpression&amp; source, DbExpressionBinding&amp; sourceBinding, DbExpression&amp; lambda)
         at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.FirstPredicateTranslatorBase.Translate(ExpressionConverter parent, MethodCallExpression call)
         at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, SequenceMethod sequenceMethod)
         at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq)
         at System.Data.Objects.ELinq.ExpressionConverter.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq)
         at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
         at System.Data.Objects.ELinq.ExpressionConverter.Convert()
         at System.Data.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable`1 forMergeOption)
         at System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
         at System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable&lt;T&gt;.GetEnumerator()
         at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source)
         at System.Data.Objects.ELinq.ObjectQueryProvider.&lt;GetElementFunction&gt;b__1[TResult](IEnumerable`1 sequence)
         at System.Data.Objects.ELinq.ObjectQueryProvider.ExecuteSingle[TResult](IEnumerable`1 query, Expression queryRoot)
         at System.Data.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute[S](Expression expression)
         at System.Data.Entity.Internal.Linq.DbQueryProvider.Execute[TResult](Expression expression)
         at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source, Expression`1 predicate)
  </code></pre>
  
  <p>I've read the Entity Framework doesn't support <code>IComparable</code>?  Is there anyway around this or does anyone know whether the functionality will be available in EF6?</p>