У меня есть база данных Microsoft SQL Server, спроектированная следующим образом: таблица Oeuvre
, другая таблица Materiau
, и, наконец, поскольку я нахожусь в отношении многих ко многим, таблица Oeuvre_Materiau
.
Я использую Visual Studio 2017 и создаю новый проект, следуя основному руководству, которое можно найти здесь: https://docs.microsoft.com/en-us/aspnet/mvc/overview/getting-started/database-first-development/
Все идет хорошо, мой дизайн БД идет хорошо, и я думаю, Visual Studio правильно понимает, как устроена моя БД, как мы можем видеть здесь:
VS, будучи умным, понимает, что таблица Oeuvre_Materiau
является просто связующим звеном между двумя таблицами.
Теперь, возможно, я ошибаюсь, но я генерирую контроллер и представления, как подсказывает мне учебник, создавая элемент леса.
ОК, у нас есть наше представление, я могу создавать и редактировать вещи, и моя таблица oeuvre
заполняется, как и должно быть, все хорошо и здорово (не беспокойтесь о других xxx_ID, тех, кто один в один отношения и работа по назначению):
Теперь я пытаюсь добавить меню DropDown с materiau_name
, определенным в моей таблице materiau
.
Каждый элемент oeuvre
может иметь несколько materiau_name
, и эти элементы materiau-name
определены в моей таблице materiau
, следовательно, таблица oeuvre_materiau
между ними состоит только из 2 элементов, materiau_id
и oeuvre_id
.
Но я понятия не имею, как это сделать. Я попытался добавить в свое представление элемент из таблицы materiau
, но я просто не могу найти как, и единственная модель, названная в моем представлении, это модель Oeuvre
.
Вот класс Oeuvre
модели:
namespace WebApplication8.Models
{
using System;
using System.Collections.Generic;
public partial class oeuvre
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public oeuvre()
{
this.materiau = new HashSet<materiau>();
}
public int oeuvre_id { get; set; }
public Nullable<System.DateTime> created_on { get; set; }
public Nullable<bool> is_deleted { get; set; }
public string titre { get; set; }
public Nullable<int> annee { get; set; }
public string emplacement_signature { get; set; }
public Nullable<int> longueur { get; set; }
public Nullable<int> largeur { get; set; }
public Nullable<int> hauteur { get; set; }
public string historique { get; set; }
public Nullable<int> categorie_id { get; set; }
public Nullable<int> lieu_id { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<materiau> materiau { get; set; }
}
}
Класс materiau
модели:
namespace WebApplication8.Models
{
using System;
using System.Collections.Generic;
public partial class materiau
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public materiau()
{
this.oeuvre = new HashSet<oeuvre>();
}
public int materiau_id { get; set; }
public string materiau_name { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<oeuvre> oeuvre { get; set; }
}
}
oeuvresController
:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using WebApplication8.Models;
namespace WebApplication8.Controllers
{
public class oeuvresController : Controller
{
private CatalogueEntities db = new CatalogueEntities();
// GET: oeuvres
public ActionResult Index()
{
return View(db.oeuvre.ToList());
}
// GET: oeuvres/Details/5
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
oeuvre oeuvre = db.oeuvre.Find(id);
if (oeuvre == null)
{
return HttpNotFound();
}
return View(oeuvre);
}
// GET: oeuvres/Create
public ActionResult Create()
{
return View();
}
// POST: oeuvres/Create
// Afin de déjouer les attaques par sur-validation, activez les propriétés spécifiques que vous voulez lier. Pour
// plus de détails, voir https://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "oeuvre_id,created_on,is_deleted,titre,annee,emplacement_signature,longueur,largeur,hauteur,historique,categorie_id,lieu_id")] oeuvre oeuvre)
{
if (ModelState.IsValid)
{
db.oeuvre.Add(oeuvre);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(oeuvre);
}
// GET: oeuvres/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
oeuvre oeuvre = db.oeuvre.Find(id);
if (oeuvre == null)
{
return HttpNotFound();
}
return View(oeuvre);
}
// POST: oeuvres/Edit/5
// Afin de déjouer les attaques par sur-validation, activez les propriétés spécifiques que vous voulez lier. Pour
// plus de détails, voir https://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "oeuvre_id,created_on,is_deleted,titre,annee,emplacement_signature,longueur,largeur,hauteur,historique,categorie_id,lieu_id")] oeuvre oeuvre)
{
if (ModelState.IsValid)
{
db.Entry(oeuvre).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(oeuvre);
}
// GET: oeuvres/Delete/5
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
oeuvre oeuvre = db.oeuvre.Find(id);
if (oeuvre == null)
{
return HttpNotFound();
}
return View(oeuvre);
}
// POST: oeuvres/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
oeuvre oeuvre = db.oeuvre.Find(id);
db.oeuvre.Remove(oeuvre);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
}
Вид Index
:
@model IEnumerable<WebApplication8.Models.oeuvre>
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.created_on)
</th>
<th>
@Html.DisplayNameFor(model => model.is_deleted)
</th>
<th>
@Html.DisplayNameFor(model => model.titre)
</th>
<th>
@Html.DisplayNameFor(model => model.annee)
</th>
<th>
@Html.DisplayNameFor(model => model.emplacement_signature)
</th>
<th>
@Html.DisplayNameFor(model => model.longueur)
</th>
<th>
@Html.DisplayNameFor(model => model.largeur)
</th>
<th>
@Html.DisplayNameFor(model => model.hauteur)
</th>
<th>
@Html.DisplayNameFor(model => model.historique)
</th>
<th>
@Html.DisplayNameFor(model => model.categorie_id)
</th>
<th>
@Html.DisplayNameFor(model => model.lieu_id)
</th>
<th></th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.created_on)
</td>
<td>
@Html.DisplayFor(modelItem => item.is_deleted)
</td>
<td>
@Html.DisplayFor(modelItem => item.titre)
</td>
<td>
@Html.DisplayFor(modelItem => item.annee)
</td>
<td>
@Html.DisplayFor(modelItem => item.emplacement_signature)
</td>
<td>
@Html.DisplayFor(modelItem => item.longueur)
</td>
<td>
@Html.DisplayFor(modelItem => item.largeur)
</td>
<td>
@Html.DisplayFor(modelItem => item.hauteur)
</td>
<td>
@Html.DisplayFor(modelItem => item.historique)
</td>
<td>
@Html.DisplayFor(modelItem => item.categorie_id)
</td>
<td>
@Html.DisplayFor(modelItem => item.lieu_id)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id=item.oeuvre_id }) |
@Html.ActionLink("Details", "Details", new { id=item.oeuvre_id }) |
@Html.ActionLink("Delete", "Delete", new { id=item.oeuvre_id })
</td>
</tr>
}
</table>
Создать вид:
@model WebApplication8.Models.oeuvre
@{
ViewBag.Title = "Create";
}
<h2>Create</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>oeuvre</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.titre, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.titre, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.titre, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.annee, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.annee, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.annee, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.emplacement_signature, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.emplacement_signature, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.emplacement_signature, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.longueur, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.longueur, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.longueur, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.largeur, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.largeur, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.largeur, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.hauteur, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.hauteur, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.hauteur, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.historique, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.historique, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.historique, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.categorie_id, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.categorie_id, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.categorie_id, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.lieu_id, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.lieu_id, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.lieu_id, "", new { @class = "text-danger" })
</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>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
Вид EDIT и DETAIL очень похожи.
Итак, я просто пытаюсь добавить выпадающий список в другом представлении, которое будет заполнено и заполнено таблицей ссылок oeuvre_materiau: