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.