C# 如何使用外键在MVC中移动多个类/表?
换句话说,如何通过外键遍历类的“层次树” 下面是树和关联的图片 我想分别在视图中循环浏览这些表。显示调查数据和类别数据很容易,因为我可以从查询字符串中引用PK和FK SurveyID。我不知道怎样才能把分类和调查联系起来,尽管超过了那个点 这是我的看法C# 如何使用外键在MVC中移动多个类/表?,c#,asp.net-mvc,foreign-keys,C#,Asp.net Mvc,Foreign Keys,换句话说,如何通过外键遍历类的“层次树” 下面是树和关联的图片 我想分别在视图中循环浏览这些表。显示调查数据和类别数据很容易,因为我可以从查询字符串中引用PK和FK SurveyID。我不知道怎样才能把分类和调查联系起来,尽管超过了那个点 这是我的看法 @using (Html.BeginForm("Save", "Surveys")) { <div class="form-group"> @Html.LabelFor(m => m.SurveyId) @H
@using (Html.BeginForm("Save", "Surveys"))
{
<div class="form-group">
@Html.LabelFor(m => m.SurveyId)
@Html.TextBoxFor(m => m.Description, new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.Description)
</div>
<div class="form-group">
@for (int i = 0; i < Model.Categories.Count; i++)
{
<ul>@Html.TextBoxFor(m => m.Categories[i].Description, new { @class = "form-control" })</ul>
@Html.HiddenFor(m => m.Categories[i].CategoryId)
@*Here is where I attempted to loop the questions based on category*@
@*@for (int j = 0; j < Model.Categories[i].Questions.Count(); j++)*@
{
@Html.TextBoxFor(m => m.Questions[j].QuestionText)
}
}
</div>
@Html.HiddenFor(m => m.User.Id)
@Html.HiddenFor(m => m.SurveyId)
@Html.AntiForgeryToken()
<button type="submit" class="btn btn-primary">Save</button>
}
@使用(Html.BeginForm(“保存”、“调查”))
{
@LabelFor(m=>m.SurveyId)
@TextBoxFor(m=>m.Description,新的{@class=“form control”})
@Html.ValidationMessageFor(m=>m.Description)
@对于(int i=0;i@Html.TextBoxFor(m=>m.Categories[i].说明,新{@class=“form control”})
@Html.HiddenFor(m=>m.Categories[i].CategoryId)
@*这里是我尝试根据类别循环问题的地方*@
@*@对于(int j=0;jm.Questions[j].QuestionText)
}
}
@Html.HiddenFor(m=>m.User.Id)
@Html.HiddenFor(m=>m.SurveyId)
@Html.AntiForgeryToken()
拯救
}
我尝试使用for(int j=0;jpublic ActionResult Edit(int id)
{
var survey = _context.Surveys.SingleOrDefault(c => c.SurveyId == id);
var categories = new List<Category>();
categories = _context.Categories.Where(c => c.SurveyId == id).ToList();
var questions = new List<Question>();
//questions = _context.Questions.Include()
//var questions = new List<Question>();
//questions = _context.Categories.Include(c => c.SurveyId == id).ToList();
if (survey == null)
return HttpNotFound();
var viewModel = new NewSurveyViewModel(survey)
{
Questions = questions,
Categories = categories
};
return View("SurveyForm", viewModel);
}
public ActionResult编辑(int-id)
{
var-survey=\u context.Surveys.SingleOrDefault(c=>c.SurveyId==id);
var categories=新列表();
categories=_context.categories.Where(c=>c.SurveyId==id.ToList();
var questions=新列表();
//问题=_context.questions.Include()
//var questions=新列表();
//问题=_context.Categories.Include(c=>c.SurveyId==id.ToList();
如果(调查==null)
返回HttpNotFound();
var viewModel=新的NewSurveyViewModel(调查)
{
问题,
类别=类别
};
返回视图(“SurveyForm”,viewModel);
}
在这里,我不确定是否应该使用include方法,但我想不出如何在类别和调查ID之间建立联系,然后再使用QuestionID
我是否比较接近?这看起来可能是数据访问问题,而不是MVC问题。如果您使用的是实体框架,请参阅如何确保加载对象 另外,不要将问题单独加载到viewModel中,因为您需要保留层次结构。你的提问框应该利用这一点
请尝试
@Html.TextBoxFor(m=>m.Categories[i].Questions[j].QuestionText)
Jamiese指出,为了让数据显示出来,必须使用第一次紧急加载,如下所示msdn.microsoft.com/en us/library/jj574232(v=vs.113).aspx
然后,我使用了一个嵌套的foreach循环
<div class="form-group">
@foreach (var category in Model.Categories.Where(q => q.SurveyId == Model.SurveyId))
{
<ul>@Html.TextBoxFor(m => category.Description, new { @class = "form-control" })</ul>
@Html.HiddenFor(m => category.CategoryId)
foreach (var question in Model.Questions.Where(q => q.CategoryId == category.CategoryId))
{
<ul>@Html.TextBoxFor(m => question.QuestionText, new { @class = "form-control" })</ul>
@Html.HiddenFor(m => question.QuestionId)
foreach (var answer in Model.Answers.Where(a => a.QuestionId == question.QuestionId))
{
<ul>@Html.TextBoxFor(m => answer.AnswerText, new { @class = "form-control" })</ul>
@Html.HiddenFor(m => answer.AnswerId)
}
}
}
</div>
@foreach(Model.Categories.Where(q=>q.SurveyId==Model.SurveyId))中的var类别
{
@Html.TextBoxFor(m=>category.Description,new{@class=“form control”})
@Html.HiddenFor(m=>category.CategoryId)
foreach(Model.Questions.Where(q=>q.CategoryId==category.CategoryId))中的var问题
{
@Html.TextBoxFor(m=>question.QuestionText,新的{@class=“form control”})
@Html.HiddenFor(m=>question.QuestionId)
foreach(Model.Answers.Where(a=>a.QuestionId==question.QuestionId))中的var-answer)
{
@Html.TextBoxFor(m=>answer.AnswerText,新的{@class=“form control”})
@Html.HiddenFor(m=>answer.AnswerId)
}
}
}
如果要在视图内部使用此查询,可以使用WITHOUT return result;
此外,您不需要定义任何数据传输类
但是如果您想在控制器内部使用,并从任何操作或json结果返回;您必须在select的每个级别使用class对象进行数据传输
例如,第一级DTO类可以是这样的
public class SurveyDTO
{
public Survey survey{get;set;}
public List<CategoriesDTO> categories {get;set;}
}
var db = new DBContext() // => this is your database context
var result = (from s in db.Surveys
select new SurveyDTO(){
survey = s,
categories = (from c in db.Categories
where c.SurveyID = s.ID
select new CategoriesDTO(){
category = c,
questions = (from q in db.Questions
where q.CategoryID = c.ID
select new QuestionsDTO(){
question = q,
answers = (from a in db.Answers
where a.QuestionID = q.ID
select a).ToList()
}).ToList() // close the questions
}).ToList() // close the categories
}).ToList();// close the surveys
return result;
我希望解释清楚,有帮助
如果您使用一个查询来获取数据,它会更快这看起来可能是数据访问问题,而不是MVC问题。如果您使用的是实体框架,请参阅以了解如何确保加载对象。急切加载是数据未显示的原因的答案,但现在它显示了每个类别下每个类别的所有问题。转换为答案,因为看起来我们走的是对的。如果它需要更新,请告诉我。我会将此标记为已为“急切加载”部分应答。之后,我可以通过使用嵌套的foreach循环,每次向下移动1级,正确地获取要显示的数据。我把我的代码贴在下面作为答案。
public class CategoriesDTO
{
public Category category {get;set;}
public List<QuestionsDTO> questions {get;set;}
}
public class QuestionsDTO
{
public Question question {get;set;}
public List<Answer> answers{get;set;}
}
var db = new DBContext() // => this is your database context
var result = (from s in db.Surveys
select new SurveyDTO(){
survey = s,
categories = (from c in db.Categories
where c.SurveyID = s.ID
select new CategoriesDTO(){
category = c,
questions = (from q in db.Questions
where q.CategoryID = c.ID
select new QuestionsDTO(){
question = q,
answers = (from a in db.Answers
where a.QuestionID = q.ID
select a).ToList()
}).ToList() // close the questions
}).ToList() // close the categories
}).ToList();// close the surveys
return result;