LINQ查询返回Grandparent,Parent,Grandchild,其中Grandchild具有价值

时间:2013-01-25 15:40:48

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

我正在构建一个用于生成调查和处理响应的系统,我有一个viewmodel SurveyTakeViewModel

namespace Survey.ViewModel
{
     public class SurveyTakeViewModel
     {
         public Models.Survey Survey { get; set; }
         public bool TakenBefore { get; set; }
     }
 }

namespace Survey.Models
{
    public class Survey
    {
        [Key]
        public int SurveyId { get; set; }

        public string Name { get; set; }
        public bool Active { get; set; }

        public string MessageStart { get; set; }
        public string MessageEnd { get; set; }

        public virtual ICollection<Question> Question { get; set; }
    }
}

namespace Survey.Models
{
    public class Question
    {
         public virtual int SurveyId { get; set; }

         [Key]
         public int QuestionId { get; set; }
         public int DisplayOrder { get; set; }
         public string QuestionText { get; set; }
         public string QuestionNote { get; set; }
         public int QuestionTypeId { get; set; }

         public virtual QuestionType QuestionType { get; set; }

         public virtual ICollection<QuestionAnswerOption> QuestionAnswerOption{ get; set; }
         public virtual ICollection<QuestionAnswer> QuestionAnswer { get; set; }
     }
 }

 namespace Survey.Models
 {
     public class QuestionAnswer
     {
         public virtual int QuestionId { get; set; }

         [Key]
         public int QuestionAnswerId { get; set; }
         public int SurveyId { get; set; }
         public string UserId { get; set; }
         public string QuestionActualResponse { get; set; }
     }
 }

这一切都适用于调查问卷,但是当用户重新访问他们之前已回答的调查问卷时,我想填充视图模型的QuestionAnswer部分,只有特定用户标识的答案,此时我得到了每一个问题。我尝试了很多不同的Linq查询,最初我的ICollections&lt;&gt;是List&lt;&gt;,我被告知可能会导致所有记录被退回。

目前我正在使用

Survey = db.Survey.FirstOrDefault(s => s.SurveyId == 1)

返回所有QuestionAnswer

我尝试过像

这样的事情
Survey = db.Survey.FirstOrDefault(a => a.Question
.Any(b => b.QuestionAnswer
.Any(c => c.UserId == userId)));

但它仍会为每个userId返回所有QuestionAnswer

1 个答案:

答案 0 :(得分:0)

您似乎知道自己想要哪种调查,但是当您访问各种属性时,他们会填充额外的信息......您希望更少的孙子记录。

我不知道足够的LinqToEntities以所需的方式限制加载(LinqToSql将使用DataLoadOptions.LoadsWithDataLoadOptions.AssociateWith)。相反,我提供了这种手动数据整形 - 加载后。也许它可以帮助专家理解这个问题,然后他们可以在LinqToEntities查询中表达它。

int surveyId = GetSurveyId();
int userId = GetUserId();

Survey mySurvey = db.Survey.FirstOrDefault(s => s.SurveyId == surveyId);

ILookup<int, QuestionAnswer> qaLookup = db.QuestionAnswer
  .Where(qa => qa.SurveyId == surveyId && qa.UserId == userId)
  .ToLookup(qa => qa.QuestionId);

foreach(Question q in mySurvey.Questions)
{
  //limit q.QuestionAnswer to only this user's answers.
  q.QuestionAnswer = qaLookup[q.QuestionId].ToList();
}