EF - Cannot apply operator '==' to operands of type 'TId' and 'TId'

Update: Here is a simple concise way that works with EF.

Add the following constraint to the GenericRepository class

where TId : IEquatable<TId>

and then use Equals method

x => x.Id.Equals(id);

Original answer:

This is a known issue with generics which normally is handled by using EqualityComparer<T>.Default instead of the == operator. However this approach doesn't work with LINQ to Entities.

One way to solve it is to build the predicate dynamically using the Expression class from the System.Linq.Expressions namespace like this:

public class GenericRepository<TEntity, TId> where TEntity: class, IIdentifyable<TId>
{
    protected static Expression<Func<TEntity, bool>> EqualsPredicate(TId id)
    {
        Expression<Func<TEntity, TId>> selector = x => x.Id;
        Expression<Func<TId>> closure = () => id;
        return Expression.Lambda<Func<TEntity, bool>>(
            Expression.Equal(selector.Body, closure.Body),
            selector.Parameters);
    }
}

and use it like this:

dbSet.FirstOrDefault(EqualsPredicate(id));

or

dbSet.Any(EqualsPredicate(id));

etc.