如何使用linq查询ASP.NET MVC 5entity framework填充视图模型

好的,这是MVC 5 ASP.NETentity framework通过范围输入收集表单数据的后续工作,我的数据库结构包含一个包含许多类别的调查,一个包含许多问题的类别,然后一个问题包含许多QuestionResults,最后是QuestionResults许多CategoryResults,在HomeController中我通过ViewModel绑定模型,但我现在要求通过Linq的上下文填充我的实体, 任何帮助将不胜感激。

我需要填充这个ViewModel,它是在一个非常有价值的堆栈溢出贡献者和我的实体的帮助下创建的,所有代码如下:

主要问题: 如何将我的实体引入SurveyVM ViewModel实例?

视图模型

namespace MyApp { public class SurveyVM { public int ID { get; set; } public string Name { get; set; } public List Categories { get; set; } } public class CategoryVM { public int ID { get; set; } public string Name { get; set; } public List Questions { get; set; } } public class QuestionVM { public int ID { get; set; } public string Title { get; set; } public int Score { get; set; } } public class QuestionResult { public int ID { get; set; } public int QuestionId { get; set; } public int QuestionScore { get; set; } } } 

链接到实体和后续数据库的模型

 public class Question { public int Id { get; set; } public string Title { get; set; } public string CreatedBy { get; set; } public DateTime? DateCreated { get; set; } public DateTime? DateModified { get; set; } public virtual Category Category { get; set; } public int CategoryId { get; set; } public virtual ICollection QuestionResult { get; set; } public virtual ICollection QuestionFeedback { get; set; } } public class QuestionResult { public int Id { get; set; } public DateTime? DateCreated { get; set; } public DateTime? DateModified { get; set; } public int QuestionScore { get; set; } //navigation properties public virtual ApplicationUser User { get; set; } public ICollection CategoryResult { get; set; } public virtual Question Question { get; set; } public int QuestionId { get; set; } } public class CategoryResult { public int Id { get; set; } public int CategoryScore {get;set;} //navigation properties public virtual QuestionResult QuestionResult { get; set; } public int QuestionResultId { get; set; } } public class Category { public int Id { get; set; } public string Title { get; set; } public string CreatedBy { get; set; } public DateTime? DateCreated { get; set; } public DateTime? DateModified { get; set; } public virtual Survey Survey { get; set; } public int SurveyId { get; set; } public virtual ICollection Question { get; set; } public virtual ICollection CategoryFeedback { get; set; } } 

HomeController的

 public ActionResult IndexSurveyViewModel() { SurveyVM model = new SurveyVM() { ID = 1, Name = "Survey 1", Categories = new List() { new CategoryVM() { ID = 1, Name = "Category A", Questions = new List() { new QuestionVM() { ID = 1, Title = "Question 1A", Score = 2 }, new QuestionVM() { ID = 2, Title = "Question 2A", Score = 4 } } }, new CategoryVM() { ID = 1, Name = "Category B", Questions = new List() { new QuestionVM() { ID = 3, Title = "Question 1B", Score = 3 }, new QuestionVM() { ID = 4, Title = "Question 2B", Score = 5 } } }, new CategoryVM() { ID = 1, Name = "Category C", Questions = new List() { new QuestionVM() { ID = 5, Title = "Question 1C", Score = 1 }, new QuestionVM() { ID = 6, Title = "Question 2C", Score = 3 } } } } }; return View(model); } [HttpPost] public ActionResult IndexSurveyViewModel(SurveyVM model) { List results = new List(); foreach (CategoryVM category in model.Categories) { foreach (QuestionVM question in category.Questions) { results.Add(new QuestionResult() { Id = question.ID, QuestionScore = question.Score }); } } return View(model); } 

视图

 @model STRA.Models.SurveyVM @{ Layout = null; }       My app   .category { display: none; margin-left: 20px; margin-top: 10px; } .category:first-of-type { display: block; } .category:first-of-type button:last-of-type { display: none; } .category:last-of-type button:first-of-type { display: none; } .question { margin-left: 20px; margin-top: 10px; } .buttons { margin: 20px; } input[type="text"] { width: 20px; } .slider { display: inline-block; width: 200px; margin-left: 20px; }    @using (Html.BeginForm()) { @Html.HiddenFor(m => m.ID) @Html.DisplayFor(m => m.Name) for (int i = 0; i < Model.Categories.Count; i++) { 
@Html.HiddenFor(m => m.Categories[i].ID) @Html.DisplayFor(m => m.Categories[i].Name) @for (int j = 0; j < Model.Categories[i].Questions.Count; j++) {
@Html.HiddenFor(m => m.Categories[i].Questions[j].ID) @Html.DisplayFor(m => m.Categories[i].Questions[j].Title) @Html.TextBoxFor(m => m.Categories[i].Questions[j].Score)
}
} } $('.slider').each(function() { var v = $(this).closest('.question').find('input[type="text"]').val(); $(this).slider({ value: v, min: 1, max: 5, change: function (event, ui) { $(this).closest('.question').find('input[type="text"]').val(ui.value); } }); }); $('.next').click(function() { $(this).closest('.category').hide().next('.category').show(); }); $('.previous').click(function() { $(this).closest('.category').hide().prev('.category').show(); });

我的代码到目前为止:

 var survey = from s in db.Surveys from c in db.Categories from q in db.Questions where s.Id == c.SurveyId where c.Id == q.CategoryId select new SurveyVM { ID = s.Id, Name = s.Title, Categories = new List() { new CategoryVM() { ID = c.Id, Name = c.Title, Questions = new List() { new QuestionVM() { ID = q.Id, Title = q.Title } } } } }; 

如何将我的实体引入SurveyVM ViewModel实例?

这可能会指向正确的方向,使用lambda表达式。

 List surveys = DbContext.Survey.Select(s=> new SurveyVM { ID = s.ID, Name = s.Name, Categories = s.Category.Select(c => new CategoryVM { ID = c.ID, Name = c.Name, Questions = c.Question.Select(q=> new QuestionVM { ID = q.ID, Title = q.Title, Score = q.Score }).ToList() }).ToList() }).SingleOrDefault(); 

这是我的头脑,因为我没有任何东西可以测试它。

另外作为旁注,我将在您的视图中使用EditorTemplates / DisplayTemplates而不是您的循环,因为它将使您的代码更易于阅读。

 for (int i = 0; i < Model.Categories.Count; i++) { 
@Html.HiddenFor(m => m.Categories[i].ID) @Html.DisplayFor(m => m.Categories[i].Name) @for (int j = 0; j < Model.Categories[i].Questions.Count; j++) {
@Html.HiddenFor(m => m.Categories[i].Questions[j].ID) @Html.DisplayFor(m => m.Categories[i].Questions[j].Title) @Html.TextBoxFor(m => m.Categories[i].Questions[j].Score)
}
}

如果您拥有域模型,并且每个域模型都有很多视图模型,那么现在是使用Automapper时机。 您可以在此处找到所有文档:

https://github.com/AutoMapper/AutoMapper/wiki/Getting-started