无法通过视图访问复合键 table,以便在该 table 中输入数据或分配正确的主键?
Can not access the composite key table through a view, in order to enter data or assign the correct primary key in that table?
我正在尝试使用代码优先方法使用 C# 和 EF 开发 ASP.NET MVC 应用程序。
我有两个 类 Actors
和 Movies
它们具有多对多关系(一个 Actor
可以在许多 Movies
中,一个Movie
可以有很多 Actors
).
一切正常,但我无法通过视图访问中间(MoviesActors
)table(此table是多对多自动生成的结果- Actors
和 Movies
之间的许多关系)。我想访问这个 table 以便我可以分配正确的主键来确定 "How many movies does a particular actor have?" 和 "How many actors have played a role in a particular movie?".
之类的东西
这些是我的模型:
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; }
}
我有两个上面的模型和三个table在数据库中。
现在从视图中,我可以访问演员模型和电影模型,但是当涉及到中间模型时 table (MoviesActors
),我无法访问它的模型,因为它不存在,这意味着我无法在视图中引用 MoviesActors
并且无法通过表单输入数据。
我想问一下我的方法是否正确,我的意思是在现实世界的应用程序中我们是否必须访问复合键 table 并进行数据输入,或者是否有更好的方法解决这个问题?
顺便说一句,这是控制器:
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 table(检查带问号的两个地方),但我无法这样做。
如果有这方面专业知识的人正在阅读这篇文章post,请指导我正确的逻辑或任何其他有助于我获得结果的方法。
非常感谢。
这是我的新剃须刀视图
@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>
@Prince_Walizada 如您所说,您有第三个 table,称为 Junction Table
,通过使用 EF,无需访问此 table .因为您可以直接将任意数量的其他实体添加到当前记录中。
例如(这是伪代码):
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" , ...}
如您所见,您不需要知道第三个 table。
中间 table 被 Entity framework 隐藏了,但是不用担心 mvc 有很棒的功能 ViewModel
来完成你的工作,这意味着你可以为中间 table 喜欢 MoviesActors
因此,
1) 你必须为你的中级 table 创建一个视图模型,比如
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) 提交表单后,您的 post 方法将添加您的 mvz
和 act
喜欢
[HttpPost]
public ActionResult Create(MoviesActorsViewModel mcvm)
{
_context.mvz.Add(mcvm.mvz);
_context.actrs.Add(mcvm.act);
return RedirectToAction("GetView", "Default");
}
注意:以上代码片段是针对一部电影和一位演员。
因此,如果您想将多个演员添加到单部电影中,请将 MoviesActorsViewModel
中的 act
属性 更改为 List
点赞 public List<Actors> act { get; set; }
并添加 multiple textbox in view 并在 post 将您的表单添加到操作方法 Create
之后添加多个参与者,例如 _context.actrs.AddRange(mcvm.act);
编辑:
I have to register a new actor too. But I want to select actors from the actors table and assign them to the new movies that gets registered.
如果在添加新电影时必须为电影分配多个演员,那么
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 填充你的 actors 以从你的 get view action 方法查看模型的动作列表
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");
}
我正在尝试使用代码优先方法使用 C# 和 EF 开发 ASP.NET MVC 应用程序。
我有两个 类 Actors
和 Movies
它们具有多对多关系(一个 Actor
可以在许多 Movies
中,一个Movie
可以有很多 Actors
).
一切正常,但我无法通过视图访问中间(MoviesActors
)table(此table是多对多自动生成的结果- Actors
和 Movies
之间的许多关系)。我想访问这个 table 以便我可以分配正确的主键来确定 "How many movies does a particular actor have?" 和 "How many actors have played a role in a particular movie?".
这些是我的模型:
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; }
}
我有两个上面的模型和三个table在数据库中。
现在从视图中,我可以访问演员模型和电影模型,但是当涉及到中间模型时 table (MoviesActors
),我无法访问它的模型,因为它不存在,这意味着我无法在视图中引用 MoviesActors
并且无法通过表单输入数据。
我想问一下我的方法是否正确,我的意思是在现实世界的应用程序中我们是否必须访问复合键 table 并进行数据输入,或者是否有更好的方法解决这个问题?
顺便说一句,这是控制器:
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 table(检查带问号的两个地方),但我无法这样做。
如果有这方面专业知识的人正在阅读这篇文章post,请指导我正确的逻辑或任何其他有助于我获得结果的方法。
非常感谢。
这是我的新剃须刀视图
@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>
@Prince_Walizada 如您所说,您有第三个 table,称为 Junction Table
,通过使用 EF,无需访问此 table .因为您可以直接将任意数量的其他实体添加到当前记录中。
例如(这是伪代码):
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" , ...}
如您所见,您不需要知道第三个 table。
中间 table 被 Entity framework 隐藏了,但是不用担心 mvc 有很棒的功能 ViewModel
来完成你的工作,这意味着你可以为中间 table 喜欢 MoviesActors
因此,
1) 你必须为你的中级 table 创建一个视图模型,比如
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) 提交表单后,您的 post 方法将添加您的 mvz
和 act
喜欢
[HttpPost]
public ActionResult Create(MoviesActorsViewModel mcvm)
{
_context.mvz.Add(mcvm.mvz);
_context.actrs.Add(mcvm.act);
return RedirectToAction("GetView", "Default");
}
注意:以上代码片段是针对一部电影和一位演员。
因此,如果您想将多个演员添加到单部电影中,请将 MoviesActorsViewModel
中的 act
属性 更改为 List
点赞 public List<Actors> act { get; set; }
并添加 multiple textbox in view 并在 post 将您的表单添加到操作方法 Create
之后添加多个参与者,例如 _context.actrs.AddRange(mcvm.act);
编辑:
I have to register a new actor too. But I want to select actors from the actors table and assign them to the new movies that gets registered.
如果在添加新电影时必须为电影分配多个演员,那么
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 填充你的 actors 以从你的 get view action 方法查看模型的动作列表
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");
}