c# - How to populate a view models using a linq query ASP.NET MVC 5 Entity Framework -
ok follow-up mvc 5 asp.net entity framework collect form data through range input , database structure consists of survey having many categories, category having many questions, question having many questionresults , questionresults having many categoryresults, in homecontroller have models being bound through viewmodel, require populated entities through context linq, any appreciated.
i need populate viewmodel, created of valuable stack-overflow contributor, entities, code below:
main question: how can bring in entities surveyvm viewmodel instance?
viewmodel
namespace myapp { public class surveyvm { public int id { get; set; } public string name { get; set; } public list<categoryvm> categories { get; set; } } public class categoryvm { public int id { get; set; } public string name { get; set; } public list<questionvm> 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; } } }
models linked entities , subsequent database
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> questionresult { get; set; } public virtual icollection<questionfeedback> 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> 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> question { get; set; } public virtual icollection<categoryfeedback> categoryfeedback { get; set; } }
homecontroller
public actionresult indexsurveyviewmodel() { surveyvm model = new surveyvm() { id = 1, name = "survey 1", categories = new list<categoryvm>() { new categoryvm() { id = 1, name = "category a", questions = new list<questionvm>() { 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<questionvm>() { 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<questionvm>() { 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<questionresult> results = new list<questionresult>(); 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); }
view
@model stra.models.surveyvm @{ layout = null; } <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="x-ua-compatible" content="ie=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>my app</title> <link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css"> <style> .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; } </style> </head> <body> @using (html.beginform()) { @html.hiddenfor(m => m.id) @html.displayfor(m => m.name) (int = 0; < model.categories.count; i++) { <div class="category"> @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++) { <div class="question"> @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) <div class="slider"></div> </div> } <div class="buttons"> <button type="button" class="next">next</button> <button type="button" class="previous">previous</button> </div> </div> } <input type="submit" /> } <!-- js includes --> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> <script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script> <script src="//ajax.aspnetcdn.com/ajax/jquery.validate/1.11.1/jquery.validate.min.js"></script> <script src="//ajax.aspnetcdn.com/ajax/mvc/4.0/jquery.validate.unobtrusive.min.js"></script> <script type="text/javascript"> $('.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(); }); </script> </body> </html>
my code far:
var survey = s in db.surveys c in db.categories q in db.questions s.id == c.surveyid c.id == q.categoryid select new surveyvm { id = s.id, name = s.title, categories = new list<categoryvm>() { new categoryvm() { id = c.id, name = c.title, questions = new list<questionvm>() { new questionvm() { id = q.id, title = q.title } } } } };
how can bring in entities surveyvm viewmodel instance?
this might point in right direction, using lambda expressions.
list<surveyvm> 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();
this off top of head dont have test with.
also side note @ using editortemplates/displaytemplates instead of loop in view make code easier read.
for (int = 0; < model.categories.count; i++) { <div class="category"> @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++) { <div class="question"> @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) <div class="slider"></div> </div> } <div class="buttons"> <button type="button" class="next">next</button> <button type="button" class="previous">previous</button> </div> </div> }
Comments
Post a Comment