在LINQ QUery中的.Select中使用索引时出错:

时间:2013-11-07 13:57:46

标签: c# linq

我有以下代码:

        //var testQuestionHeaders = _questionsRepository.GetAll()
        //        .Where(m => m.Problem != null &&
        //        m.Problem.SubTopic != null &&
        //        m.Problem.SubTopic.Topic != null &&
        //        m.Problem.SubTopic.Topic.SubjectId == 1)
        //        .Select(m => new TestQuestionHeader
        //        {
        //            Id = 1,
        //            QId = m.QuestionId,
        //            A = false,
        //            C = 0,
        //            F = 0
        //        })
        //        .ToList();

        var testQuestionHeaders = _questionsRepository.GetAll()
            .Where(m => m.Problem != null &&
            m.Problem.SubTopic != null &&
            m.Problem.SubTopic.Topic != null &&
            m.Problem.SubTopic.Topic.SubjectId == 1)
            .Select((m, index) => new TestQuestionHeader
            {
                Id = index + 1,
                QId = m.QuestionId,
                A = false,
                C = 0,
                F = 0
            })
            .ToList();

第一个代码(现已注释掉)可以工作,但是当我添加索引的使用时,我得到以下异常:

System.NotSupportedException was unhandled by user code
  HResult=-2146233067
  Message=LINQ to Entities does not recognize the method 'System.Linq.IQueryable`1[Models.Http.TestQuestionHeader] Select[Question,TestQuestionHeader](System.Linq.IQueryable`1[Models.Core.Question], System.Linq.Expressions.Expression`1[System.Func`3[Models.Core.Question,System.Int32,Models.Http.TestQuestionHeader]])' method, and this method cannot be translated into a store expression.
  Source=EntityFramework
  StackTrace:
       at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.DefaultTranslator.Translate(ExpressionConverter parent, MethodCallExpression call)
       at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq)
       at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq)
       at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
       at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.Convert()
       at System.Data.Entity.Core.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable`1 forMergeOption)
       at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClassb.<GetResults>b__a()
       at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
       at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClassb.<GetResults>b__9()
       at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation)
       at System.Data.Entity.Core.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
       at System.Data.Entity.Core.Objects.ObjectQuery`1.<System.Collections.Generic.IEnumerable<T>.GetEnumerator>b__0()
       at System.Lazy`1.CreateValue()
       at System.Lazy`1.LazyInitValue()
       at System.Data.Entity.Internal.LazyEnumerator`1.MoveNext()
       at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
       at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
       at Services.QuestionService.GetTestQuestionHeadersBySubject(Int32 subjectId) in S146\Services\QuestionService.cs:line 100
       at Web.Controllers.TestController.CreateTestData() in S146\WebRole1\Controllers\TestController.cs:line 39
       at lambda_method(Closure , Object , Object[] )
       at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass10.<GetExecutor>b__9(Object instance, Object[] methodParameters)
       at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments)
       at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken)
  InnerException: 

有人可以给我一些建议。这是非常可重复的,对我来说,有一些方法可以将Id设置为输出中的不同值。

2 个答案:

答案 0 :(得分:2)

嗯,例外很清楚:

你不能在linq to entities查询中使用Select(带有Func<TSource, int, TResult> selector参数的那个)的重载(在IQueryable<T>上用于linq到实体查询)。

所以如果你需要它,你必须先列举

.ToList()
.Select((m, index) =>...

答案 1 :(得分:2)

1)在select之前调用.ToList()会让你做一个巨大的选择(如果你的表有多个filelds)什么都没有

2)您可以使用:./ / p>而不是调用.ToList()或.ToArray(),这会让您失去懒惰的枚举优势。

var lazyEnumerated = Enumerable.Select(testQuestionHeaders , (m, index) =>
                {
                    m.Id += index;
                    return m;
                });

其中testQuestionHeaders是您注释掉的第一个选择。