在LINQ和EntityFramework中使用ToList()时出现NotSupportedException异常

4

我有一个查询看起来像这样:

    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)

**


6
“.ToList()”方法引发了异常,因为它是LINQ表达式中的一个方法(例如“.ToArray()”、“.Single()”等方法之一),会实际“评估”该表达式。在此之前,该表达式甚至没有到达数据库。在这一点上,有许多事情正在发生,其中一部分显然会引发此异常。请贴出完整的异常/堆栈跟踪信息。 - Kirk Woll
1
感谢@Saher发布堆栈跟踪。那么现在,z.field的类型是什么?field是什么? - Kirk Woll
1
然后ivowiblo是一个出色的心灵读者。他准确地回答了问题。 ;) - Kirk Woll
是的,他做到了。谢谢你,柯克,你做了出色的侦探工作! - Saher Ahwal
呵呵,不如ivowiblo好。 ;) - Kirk Woll
可能是重复的问题:ASP.NET Entity Framework NotSupportedException - Saher Ahwal
1个回答

11
问题在于 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来完成它。非常感谢。 - Saher Ahwal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接