我正在构建一个用于生成调查和处理响应的系统,我有一个视图模型 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; }
}
}
对于问卷来说,这一切都很好用,但是当用户重新访问他们之前回答过的调查问卷时,我想用仅由特定用户ID的答案填充视图模型的QuestionAnswer部分,目前我得到每个答案。我已经尝试了大量不同的Linq查询,最初我的ICollections<>是List<>,我被告知这可能会导致所有记录都被返回。
目前我正在使用
Survey = db.Survey.FirstOrDefault(s => s.SurveyId == 1)
返回所有问答
我试过这样的事情
Survey = db.Survey.FirstOrDefault(a => a.Question
.Any(b => b.QuestionAnswer
.Any(c => c.UserId == userId)));
但它仍然返回每个用户 ID 的所有问题答案
似乎您知道自己想要哪个调查,但是当您访问各种属性时,它们会填充额外的信息......你想要更少的孙子记录。
我不知道足够的LinqToEntities来限制所需的加载(LinqToSql将使用DataLoadOptions.LoadsWith
和DataLoadOptions.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();
}