EF - 无法将 '==' 操作符应用于 'TId' 类型和 'TId' 类型的操作数。

26 浏览
0 Comments

EF - 无法将 '==' 操作符应用于 'TId' 类型和 'TId' 类型的操作数。

我有一个使用Entity Framework 6.x的通用类。\n

public class GenericRepository where 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)

0
0 Comments

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;

}

}

0
0 Comments

问题原因是在使用泛型时,无法直接比较不同类型的`TId`。解决方法是限制`TId`为引用类型,或者根据不同的`TId`类型创建不同的类来支持。

在上述代码中,只有在将`TId`类型限制为引用类型时才能通过编译。但是,这可能并不适用于你的情况,所以你需要创建不同的类来支持GUID、int或long类型的id值。

非常感谢。这确实解决了问题。但是,由于我实际上想使用`int`作为Id,所以实现起来会有问题。

0
0 Comments

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中无法使用'=='操作符比较泛型类型的问题。

0