EF - 无法将 '==' 操作符应用于 'TId' 类型和 'TId' 类型的操作数。
EF - 无法将 '==' 操作符应用于 'TId' 类型和 'TId' 类型的操作数。
我有一个使用Entity Framework 6.x的通用类。\n
public class GenericRepositorywhere TEntity : class, IIdentifyable { public virtual TEntity GetById(TId id) { using (var context = new DbContext()) { var dbSet = context.Set (); var currentItem = dbSet.FirstOrDefault(x => x.Id.Equals(id)); return currentItem; } } public virtual bool Exists(TId id) { using (var context = new DbContext()) { var dbSet = context.Set (); var exists = dbSet.Any(x => x.Id.Equals(id)); return exists; } } }
\n还有这些接口:\n
public interface IIdentifyable : IIdentifyable{ } public interface IIdentifyable { TId Id { get; } }
\n和这些实体:\n
public class CustomerEntity : IIdentifyable{ public string Name { get; set; } public int Id { get; set; } } public class ProductEntity : IIdentifyable { public string Name { get; set; } public Guid Id { get; set; } }
\n我的问题是它无法编译。我收到以下错误:\n
无法将运算符“==”应用于类型“TId”和“TId”
\n我尝试将其更改为`x => Equals(x.Id, id)`,但是EF无法将其翻译。有没有办法解决这个问题?\n我知道可以使用`Find()`而不是`FirstOrDefault`。但是我需要它用于更多的方法。是否有办法让EF将`TId`与`TId`进行比较?`TId`目前只能是`int`和`guid`。我已经看到了下面的问题,但它们没有涉及到将其翻译成SQL的问题。\n[Can\'t operator == be applied to generic types in C#?](https://stackoverflow.com/questions/390900/cant-operator-be-applied-to-generic-types-in-c)\n[How to solve Operator \'!=\' cannot be applied to operands of type \'T\' and \'T\'](https://stackoverflow.com/questions/8982645/how-to-solve-operator-cannot-be-applied-to-operands-of-type-t-and-t)
EF - Cannot apply operator '==' to operands of type 'TId' and 'TId'问题的原因是不能使用==运算符来比较泛型类型。解决方法是使用Equals运算符。
在代码中,通过使用Equals运算符来比较id值,可以解决这个问题。具体实现如下:
public virtual TEntity GetById(TId id)
{
using (var context = new DbContext())
{
var dbSet = context.Set<TEntity>();
var currentItem = dbSet.FirstOrDefault(x => x.Id.Equals(id));
return currentItem;
}
}
EF - Cannot apply operator '==' to operands of type 'TId' and 'TId'问题的原因是泛型类型无法使用'=='操作符进行比较。解决方法是使用Equals
方法来替代'=='操作符。
在EF中,使用EqualityComparer<T>.Default
来处理泛型类型比较是行不通的。为了解决这个问题,可以使用System.Linq.Expressions
命名空间中的Expression
类动态构建谓词。
首先,在GenericRepository
类中添加以下约束:
where TId : IEquatable<TId>
然后使用Expression
类来构建谓词:
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); } }
最后,可以通过以下方式使用该谓词:
dbSet.FirstOrDefault(EqualsPredicate(id));
或
dbSet.Any(EqualsPredicate(id));
这样就可以解决EF中无法使用'=='操作符比较泛型类型的问题。