【问题标题】:NotSupportedException using ToList() in LINQ and EntityFrameworkNotSupportedException 在 LINQ 和 EntityFramework 中使用 ToList()
【发布时间】:2012-07-20 02:32:34
【问题描述】:

我的查询如下所示:

    var q = from x in db.Table1
                where x.Timestamp.CompareTo(fromDate) >= 0
                   && x.Timestamp.CompareTo(toDate) < 0
                select x;

    var q_list = q.ToList(); // this works fine
    var g = q.Where(z=> z.Table2.Equals(ns));  // ns is instance of Table2 not Table1
    var g_list = g.ToList(); // this throws exception 

例外:

**

System.NotSupportedException was unhandled
  Message=Unable to create a constant value of type ...

我有很多这样的功能,我不想重复查询,我需要使用 Where、GroupBy ...等功能。

完整的异常跟踪:

**

System.NotSupportedException was unhandled
  Message=Unable to create a constant value of type 'DataAccessLayer.Model.Table2. Only primitive types ('such as Int32, String, and Guid') 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.OneLambdaTranslator.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.Data.Entity.Internal.Linq.InternalQuery`1.GetEnumerator()
       at System.Data.Entity.Infrastructure.DbQuery`1.System.Collections.Generic.IEnumerable<TResult>.GetEnumerator()
       at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)

**

【问题讨论】:

  • 好吧,.ToList() 对异常负责只是因为它是一种方法(在许多方法中,例如.ToArray().Single() 等)实际上会“评估”LINQ 表达式.在那之前,它甚至没有命中数据库。在这一点上,有很多事情正在发生,其中一部分显然是抛出这个异常。您能否发布完整的异常/堆栈跟踪?
  • 感谢@Saher 发布堆栈跟踪。那么现在,z.field 的类型是什么? field 是什么?
  • 那么 ivowiblo 是一位出色的读心者。他确定了答案。 ;)
  • 是的,他做到了。谢谢柯克,你做了很棒的侦探工作!
  • 嘿,不如 ivowiblo。 ;)

标签: c# .net linq entity-framework


【解决方案1】:

问题在于 EntityFramework 不理解非原始类型。你需要做的是:

var g = q.Where(z => z.field.Id.Equals(ns.Id)); 

请记住,如果您有 Equals 的自定义实现,则无法将其转换为正确的 t-sql。如果您仍然想执行该实现,则需要在内存中执行:

// note it's using q_list instead of q
var g = q_list.Where(z => z.field.Equals(ns));  

【讨论】:

  • 我想我会通过 ID 来做。非常感谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-25
  • 1970-01-01
  • 1970-01-01
  • 2020-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多