无法通过视图访问组合键表,以便在该表中输入数据或分配正确的主键?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无法通过视图访问组合键表,以便在该表中输入数据或分配正确的主键?相关的知识,希望对你有一定的参考价值。
我正在尝试使用C#和EF开发一个带有代码优先方法的ASP.NET MVC应用程序。
我有两个类Actors
和Movies
有多对多的关系(Actor
可以在许多Movies
,Movie
可以有许多Actors
)。
一切正常,但我无法通过视图访问中间(MoviesActors
)表(此表是由于Actors
和Movies
之间的多对多关系而自动生成的)。我想访问这个表,以便我可以分配正确的主键来确定“特定演员有多少部电影?”之类的内容。和“有多少演员在某部电影中扮演过角色?”。
这些是我的模特:
public class Actors
{
public Actors()
{
this.mvz = new HashSet<Movies>();
}
public int Id { get; set; }
public string actor_name { get; set; }
public string country { get; set; }
public virtual ICollection<Movies> mvz { get; set; }
}
public class Movies
{
public Movies()
{
this.actz = new HashSet<Actors>();
}
public int Id { get; set; }
public string Movie_title { get; set; }
public string genre { get; set; }
public virtual ICollection<Actors> actz { get; set; }
}
我有两个模型和数据库中的三个表。
现在从一个角度来看,我可以访问actor模型和电影模型,但是当涉及到中间表(MoviesActors
)时,我无法访问它的模型,因为它不存在,这意味着我无法在视图中引用MoviesActors
无法通过表单输入数据。
我想问一下我的方法是否正确,我的意思是在现实世界的应用程序中,我们是否必须访问复合密钥表并进行数据输入,还是有更好的方法来解决这个问题?
顺便说一下这是控制器:
public ActionResult DataEntry()
{
return View();
}
[HttpPost]
public ActionResult Add(??? mva)
{
_context.act.Add(mva.act);
_context.mvz.Add(mva.mvz);
_context.SaveChanges();
return RedirectToAction("Index","Actors");
}
这就是观点:
@model Many_To_Many_Relationship_Latest.?.?
@{
ViewBag.Title = "DataEntry";
Layout = "~/Views/Shared/_Layout.cshtml";
}
在顶部,我应该能够通过Model或ViewModel访问MoviesActors表(用问号检查两个地方),但我无法这样做。
如果有这方面的专业知识的人正在阅读这篇文章,请用正确的逻辑或任何其他方法指导我,以帮助我获得结果。
提前谢谢了。
这是我的新剃刀观点
@model Many_To_Many_Relationship_Latest.ViewModel.MoviesActorsViewModel
<script src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
@{
ViewBag.Title = "DataEntry";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h5>Enter Data in Movies_Actors Table</h5>
@using (Html.BeginForm("Add","MoviesActors"))
{
<div class="form-group">
@Html.LabelFor(a=> a.mvz.Movie_title)
@Html.TextBoxFor(a=> a.mvz.Movie_title, new { @class="form-control"})
</div>
<div class="form-group">
@Html.LabelFor(a => a.mvz.genre)
@Html.TextBoxFor(a => a.mvz.genre, new { @class = "form-control" })
</div>
foreach (var item in Model.act)
{
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<div class="checkbox control-group">
<label>
<!-- SEE id property here, I've made it dynamic -->
<input type="checkbox" id="cb_@item.Id" value="@item.Id" class="checkBoxClass" />
<label>@item.actor_name</label>
</label>
</div>
</div>
</div>
}
<div>
<input type="hidden" name="Ids" id="Ids" />
</div>
<button type="submit" class="btn btn-primary">Save</button>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
<script>
$(function () {
var ids = [];
$(".checkBoxClass").change(function () {
if (this.checked) {
ids.push(this.value);
}
else {
var index = ids.indexOf(this.value);
ids.splice(index, 1);
}
$('#ids').val(ids);
});
});
</script>
实体框架隐藏了中间表,但不要担心mvc有ViewModel
完成你的工作的神话般的功能,这意味着你可以创建像MoviesActors
这样的中间表的视图
因此对于,
1)你必须为你的中间表创建一个视图模型
public class MoviesActorsViewModel
{
public MoviesActorsViewModel()
{
mvz = new Movies();
act = new Actors();
}
public Movies mvz { get; set; }
public Actors act { get; set; }
}
2)为上面的视图模型添加视图
public ActionResult GetView()
{
MoviesActorsViewModel mcvm = new MoviesActorsViewModel();
return View(mcvm);
}
3)然后你对上面的动作方法的看法就像。
以下剃须刀仅供您理解。你的实际剃须刀可能与此有所不同。
@model WebApplication2.Controllers.MoviesActorsViewModel
@{
ViewBag.Title = "GetView";
}
<h2>GetView</h2>
@using (Html.BeginForm("Create", "Default", FormMethod.Post))
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>MoviesActorsViewModel</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
//mvz fields below
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
@Html.TextBoxFor(model => model.mvz.movie_title, new { htmlAttributes = new { @class = "form-control" } })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
@Html.TextBoxFor(model => model.mvz.genre, new { htmlAttributes = new { @class = "form-control" } })
</div>
</div>
//act fields below
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
@Html.TextBoxFor(model => model.act.actor_name, new { htmlAttributes = new { @class = "form-control" } })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
@Html.TextBoxFor(model => model.act.country_of_birth, new { htmlAttributes = new { @class = "form-control" } })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
4)提交表格后,你的邮政方法将添加你的mvz
和act
像
[HttpPost]
public ActionResult Create(MoviesActorsViewModel mcvm)
{
_context.mvz.Add(mcvm.mvz);
_context.actrs.Add(mcvm.act);
return RedirectToAction("GetView", "Default");
}
注意:上面的代码片段适用于一部电影和一部演员。因此,如果你想在单个电影中添加多个演员,那么将你在act
中的MoviesActorsViewModel
属性更改为List
像public List<Actors> act { get; set; }
并添加multiple textbox in view并在发布你的表单到动作方法之后Create
添加像_context.actrs.AddRange(mcvm.act);
这样的多个演员
编辑:
我也要注册一个新演员。但是我想从actors表中选择actor并将它们分配给已注册的新电影。
如果你必须在添加新电影的同时为影片分配多个演员
1)你看模型是
public class MoviesActorsViewModel
{
public MoviesActorsViewModel()
{
mvz = new Movies();
act = new List<Actors>();
}
public Movies mvz { get; set; }
public List<Actors> act { get; set; }
public string[] ids { get; set; }
}
2)从db填充actor以从get view action方法查看模型的act列表
public ActionResult GetView()
{
MoviesActorsViewModel mcvm = new MoviesActorsViewModel();
mcvm.act = _context.actrs.ToList();
return View(mcvm);
}
3)在剃须刀视图中,您必须输入一部电影并为其选择多个演员,然后只需为每个演员选中复选框,并将其各自的id
值添加到数组中,然后通过表单提交传递此数组。
@model WebApplicationMVC1.Controllers.MoviesActorsViewModel
<script src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
@{
ViewBag.Title = "GetView";
}
<h2>GetView</h2>
@using (Html.BeginForm("Create", "Default1", FormMethod.Post))
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>MoviesActorsViewModel</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
//mvz fields below
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
@Html.TextBoxFor(model => model.mvz.movie_title, new { htmlAttributes = new { @class = "form-control" } })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
@Html.TextBoxFor(model => model.mvz.genre, new { htmlAttributes = new { @class = "form-control" } })
</div>
</div>
//act fields below from list of actors
@foreach (var item in Model.act)
{
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<div class="checkbox control-group">
<label>
<!-- SEE id property here, I've made it dynamic -->
<input type="checkbox" id="cb_@item.Id" value="@item.Id" class="checkBoxClass" />
<label>@item.actor_name</label>
</label>
</div>
</div>
</div>
}
<div>
<input type="hidden" name="ids" id="ids" />
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
<script>
$(function () {
var ids = [];
$(".checkBoxClass").change(function () {
if (this.checked) {
ids.push(this.value);
}
else {
var index = ids.indexOf(this.value);
ids.splice(index, 1);
}
$('#ids').val(ids);
});
});
</script>
4)将表单提交到下面的操作后,你可以遍历每个演员的id
并将其保存到数据库中
[HttpPost]
public ActionResult Create(MoviesActorsViewModel mcvm)
{
_context.mvz.Add(mcvm.mvz);
foreach (var id in mcvm.ids)
{
int id1 = Convert.ToInt32(id);
Actors act = _context.actrs.Find(x => x.Id == id1);
_context.actrs.Add(act);
}
return RedirectToAction("GetView", "Default");
}
@Prince_Walizada如你所说,你有第三个表叫做Junction Table
,使用EF就不需要访问这个表了。因为您可以直接将任意数量的其他实体添加到当前记录中。
例如(这是伪代码):
var Movie = MyContext.Movies.Where(P=>Title.Contains("Star war")).FirstOrDefault();
Movie.Actors.Add(new Actor() { Name = "Mike" , ...}
Movie.Actors.Add(new Actor() { Name = "Joe" , ...}
Movie.Actors.Add(new Actor() { Name = "Daniel" , ...}
你也可以反过来这样做:
var Actor = MyContext.Movies.Where(P=>Name.Contains("Mike")).FirstOrDefault();
Actor.Movies.Add(new Movie() { Title = "World of War" , ...}
Actor.Movies.Add(new Movie() { Title = "hobbits" , ...}
Actor.Movies.Add(new Movie() { Title = "toy story" , ...}
如您所见,您不需要知道第三个表。
以上是关于无法通过视图访问组合键表,以便在该表中输入数据或分配正确的主键?的主要内容,如果未能解决你的问题,请参考以下文章