【问题标题】:LINQ to Entities does not recognize the method: LastOrDefault [duplicate]LINQ to Entities 无法识别该方法:LastOrDefault [重复]
【发布时间】:2017-02-03 04:17:24
【问题描述】:

概述: 在 CompletedQuestions 表中,UserId 对应于完成该问题的用户。 Id 属性对应于 Questions 表中的问题之一。我知道,我没有正确指定关系。但我不是很有经验。我只是想完成一个项目,然后我会在了解更多信息后回来修复那些糟糕的编码实践。我无法理解以下异常。

LINQ to Entities does not recognize the method 'Riddle.Models.CompletedQuestion LastOrDefault[CompletedQuestion](System.Linq.IQueryable`1[Riddle.Models.CompletedQuestion])' method, and this method cannot be translated into a store expression.

    Line 46:                 if (RiddleCompleted == null)
    Line 47:                 {
    Line 48:                     var lastCompletedQuestion = _db.CompletedQuestions.Where(q => q.UserId == currentUserId) // exception occurs in this line
    Line 49:                                                                              .OrderBy(q => q.QuestionNumber)
    Line 50:                                                                              .LastOrDefault();

发生异常的动作:

public ActionResult Riddle(int Id)
        {
            string currentUserId = User.Identity.GetUserId();
            var riddle = _db.Riddles.Where(r => r.Id == Id).Single();

            if (riddle.User.Id == User.Identity.GetUserId())
            {
                var question = riddle.Questions.Where(q => q.QuestionNumber == 1).SingleOrDefault();
                if (question == null)
                {
                    return View("NoMoreQuestions");
                }
                return View("RiddleOwner", question);
            }
            else
            {

                var RiddleCompleted = _db.CompletedRiddles.Where(r => r.Id == Id && r.UserId == currentUserId).SingleOrDefault();
                if (RiddleCompleted == null)
                {
                    var lastCompletedQuestion = _db.CompletedQuestions.Where(q => q.UserId == currentUserId)  // exception occurs in this line
                                                                             .OrderBy(q => q.QuestionNumber)
                                                                             .LastOrDefault();
                    if (lastCompletedQuestion == null)
                    {
                        var question = riddle.Questions.Where(q => q.QuestionNumber == 1).Single();
                        return View(question);
                    }

                    else
                    {
                        var question = riddle.Questions.Where(q => q.QuestionNumber == lastCompletedQuestion.QuestionNumber + 1).SingleOrDefault();
                        return View(question);
                    }
                }
                else
                {
                    return View("NoMoreQuestions");
                }
            }
        }

CompletedQuestion 模型:

public class CompletedQuestion
{
    public int Id { get; set; }
    public string UserId { get; set; }
    public int QuestionNumber { get; set; }
}

问题模型:

  public class Question
    {
        public int Id { get; set; }
        public string Body { get; set; }
        public string Answer { get; set; }
        public Riddle Riddle { get; set; }
        [Column(TypeName ="datetime2")]
        public DateTime CreationDate { get; set; }
        public int QuestionNumber { get; set; }
    }

【问题讨论】:

    标签: c# linq asp.net-mvc-5 entity-framework-6


    【解决方案1】:

    LastOrDefault() 不受 Linq To 实体支持。因此它可以在内存中的集合上工作,但在您尝试查询数据库时却不行。

    这是一种有效的处理方式:

    var lastCompletedQuestion = 
    _db.CompletedQuestions.Where(q => q.UserId == currentUserId)
    .OrderByDescending(q => q.QuestionNumber)
    .FirstOrDefault() 
    
                                                                             ;
    

    【讨论】:

      【解决方案2】:

      Entity framework/linq2sql 通过将已编译的 C#/IL 转换为 SQL 来工作。它只能转换它知道的方法。该错误告诉您 LastOrDefault 不是其中之一。

      您可以通过将 .ToList() 放在 LastOrDefault 之前来解决此问题,这会将其从 sql-converter 转移到 vanilla C# 中,您将获得 LastOrDefault 的常规工作版本。或者您可以翻转订单并使用它可以翻译的 FirstOrDefault。

      【讨论】:

      • 只是想强调,即使在转换为列表然后使用 LastOrDefault 对我也不起作用,翻转列表然后使用 FirstOrDefault 也没有,但很高兴知道 LINQ to Entities 不支持这些fns。
      猜你喜欢
      • 1970-01-01
      • 2021-11-06
      相关资源
      最近更新 更多