gpt4 book ai didi

c# - 是否可以使用 IComparable 比较 Entity Framework 中的实体?

转载 作者:太空狗 更新时间:2023-10-30 01:05:28 25 4
gpt4 key购买 nike

我有一个实现 IComparable 的 POCO 类。

public interface IEntity : IComparable
{
long Id { get; set; }

Func<IEntity, bool> CompareFunction { get; }
}

public abstract class BaseEntity : IEntity
{
public virtual long Id { get; set; }

public Func<IEntity, bool> CompareFunction
{
get
{
Func<IEntity, bool> 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 <(BaseEntity left, BaseEntity right)
{
return Compare(left, right) < 0;
}

public static bool operator >(BaseEntity left, BaseEntity right)
{
return Compare(left, right) > 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);
}
}

DbContext 中有用于我的 POCO 类的 DbSet

但是,当我执行 BaseRepository.Exists() 时,我得到了一个 System.NotSupportedException

public class BaseRepository<TEntity> : IRepository<TEntity> where TEntity : class, IEntity
{
...

private TEntity Exists(TEntity entity)
{
return Context.DbSet<TEntity>.FirstOrDefult(i => i.CompareTo(entity) == 0);
}

private TEntity ExistsV2(TEntity entity)
{
return Context.DbSet<TEntity>.FirstOrDefult(i => i.CompareFunction(entity) == 0);
}

...
}

异常堆栈跟踪看起来像...

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& binding)
at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, DbExpression& source, DbExpressionBinding& sourceBinding, DbExpression& 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<T>.GetEnumerator()
at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source)
at System.Data.Objects.ELinq.ObjectQueryProvider.<GetElementFunction>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)

当我执行 BaseRepository.ExistsV2() 时,我得到一个略有不同的 System.NotSupportedException

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& binding)
at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, DbExpression& source, DbExpressionBinding& sourceBinding, DbExpression& 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<T>.GetEnumerator()
at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source)
at System.Data.Objects.ELinq.ObjectQueryProvider.<GetElementFunction>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)

我读过 Entity Framework 不支持 IComparable?无论如何,有没有人知道该功能是否会在 EF6 中可用?

最佳答案

不,你不能这样做。

EF 要求所有操作都能够 100% 在服务器端执行。支持 IComparableIEquatable 需要 EF 能够将任意 IL 转换为 SQL,而它目前还不能。

否则,它必须将整个未过滤的结果集传递给客户端。您可以使用 AsEnumerable() 实现这一点:

Context.DbSet<TEntity>.AsEnumerable().FirstOrDefault(i => i.CompareTo(entity) == 0);

虽然这当然会运行得很慢,所以如果表很大,我不会推荐它。

关于c# - 是否可以使用 IComparable 比较 Entity Framework 中的实体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18692381/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com