【问题标题】:Entity Framework throws NotSupportedException after calling Any or Count实体框架在调用 Any 或 Count 后抛出 NotSupportedException
【发布时间】:2014-01-30 08:45:06
【问题描述】:

我有以下代码:

private void Import(DbSet<DBEntity> dbEntities, IEnumerable<ExcelEntity> entities, ClapEntities context)
{
    foreach (var me in entities)
    {
        try
        {
            var dbe = dbEntities.Where(IsEqualRecord(me, context));
            bool hasElement = dbe.Any(); //Line which throws the exception
        }
        catch (Exception ex)
        {
            //...
        }
    }
}

protected abstract Expression<Func<DBEntity, bool>> IsEqualRecord(ExcelEntity entity, ClapEntities context);

Any() 扩展会抛出 NotSupportedException

System.Exception:无法将实体映射到数据库。映射器:[CuttingToolImport];行号:[153] ---> System.NotSupportedException:方法“First”只能用作最终查询操作。请考虑在此实例中改用“FirstOrDefault”方法。
在 System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.FirstTranslator.TranslateUnary(ExpressionConverter 父级,DbExpression 操作数,MethodCallExpression 调用)
在 System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter 父级,MethodCallExpression linq)
在 System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
在 System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.EqualsTranslator.TypedTranslate(ExpressionConverter 父级,BinaryExpression linq)
在 System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.BinaryTranslator.TypedTranslate(ExpressionConverter 父级,BinaryExpression linq)
在 System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
在 System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateLambda(LambdaExpression lambda,DbExpression 输入)
在 System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter 父,MethodCallExpression 调用,DbExpression& 源,DbExpressionBinding& sourceBinding,DbExpression& lambda)
在 System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter parent, MethodCallExpression call)
在 System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter 父级,MethodCallExpression linq)
在 System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
在 System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.AggregateTranslator.Translate(ExpressionConverter parent, MethodCallExpression call)
在 System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter 父级,MethodCallExpression linq)
在 System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.Convert()
在 System.Data.Entity.Core.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable1 forMergeOption)
at System.Data.Entity.Core.Objects.ObjectQuery
1.c_DisplayClassb.b_a()
在 System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
at System.Data.Entity.Core.Objects.ObjectQuery
1.c_DisplayClassb.b_9()
在 System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func1 operation)
at System.Data.Entity.Core.Objects.ObjectQuery
1.GetResults(Nullable1 forMergeOption)
at System.Data.Entity.Core.Objects.ObjectQuery
1..GetEnumerator>b__0()
在 System.Lazy1.CreateValue()
at System.Lazy
1.LazyInitValue()
在 System.Data.Entity.Internal.LazyEnumerator1.MoveNext()
at System.Linq.Enumerable.Single[TSource](IEnumerable
1 来源)
在 System.Linq.Queryable.Count[TSource](IQueryable1 source)
at CLAP.Models.Import.ImportMapping.ImportBase
2.Import(DbSet1 dbEntities, IEnumerable1 个实体,ClapEntities 上下文)
--- 内部异常堆栈跟踪结束 ---

如您所见,Any() 扩展(或Count() 扩展)使用First() 内部扩展,这是不允许的。我不知道如何解决该错误。

正是这段代码在 Entity Framework 版本 5 或 6 和

上运行了很多个月
Microsoft SQL Server 2012 - 11.0.2100.60 (X64) Express Edition (64-bit) on
Windows NT 6.1 <X64> (Build 7601: Service Pack 1)

有人知道如何解决这个错误吗?

【问题讨论】:

  • 这可能是IsEqualRecord方法的问题,可能无法翻译成sql。
  • 好吧。但是我一个月没有对整个代码进行任何更改。它随时可用。
  • 破坏行为的改变是什么?
  • 当然这很奇怪,但它必须在你的IsEqualRecord 方法中,因为Any 这样总是有效的。 IsEqualRecord 在调用Any 时执行。
  • 可以显示IsEqualRecord的出处吗?

标签: c# sql entity-framework


【解决方案1】:

您应该改用.FirstOrDefault(),当数据集中没有实体时,它将返回NULL

bool hasElement = dbe.FirstOrDefault() != null;

您的代码中的另一个可能问题是您正在使用自定义IsEqualRecord 方法,该方法应该包含可以翻译成SQL的代码em>。

【讨论】:

  • 首先,我不能修改EntityFramework里面的代码。我不调用 First()。我调用 Any() 或 Count() 来调用 First()。接下来就是IsEqualRecord函数可以翻译成SQL了。它现在已经被翻译成 SQL 很多个月了。在这里解决了:stackoverflow.com/questions/18283307/…
  • @thefiloe 好吧,也许我不清楚。而不是.Any() 使用.FirstOrDefault() != null
  • 我认为dbe.FirstOrDefault() 会抛出同样的异常。看到这一点得到证实会很有趣,因为这真的会把它归结为IsEqualRecord
  • 我知道这是旧的,但我刚刚遇到它。我通过在 .any() 之前添加 .toList() 来修复我的事件。希望这对将来的某人有所帮助。 dbContext.MyCoolTable.ToList().Any()
  • @Timothy 你是对的,因为在调用 .ToList() 之后你将使用 Linq to Objects 而不是 Linq to Entities但是你不应该这样做。这种方法的巨大缺点是您会将所有数据集加载到内存中,然后从多个角度(内存利用率、性能)过滤掉低效所需的项目。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多