I have a Microsoft SQL Server database designed as follows: a table Oeuvre
, another table Materiau
, and finally as I'm in a many-to-many relationship, a table Oeuvre_Materiau
.
I'm using Visual Studio 2017, and creating a new project following the basic tutorial that can be found here: https://learn.microsoft.com/en-us/aspnet/mvc/overview/getting-started/database-first-development/
Everything is going fine, my DB design is going fine, and Visual Studio is, I think, understanding correctly how my DB is designed, as we can see here:
VS, being smart, understands that the table Oeuvre_Materiau
is just a link between the two tables.
Now, and it may be were I'm going wrong, but I'm generating the controller and the views as the tutorial tells me, by creating a scaffolded item.
OK, we have our view, I can create and edit things and my oeuvre
table is populated as should be, everything is fine and dandy (don't worry about the other xxx_ID, those a for a one to one relationship and work as intended) :
Now, I'm trying to add a DropDown menu with the materiau_name
defined in my materiau
table.
Each oeuvre
item can have multiple materiau_name
, and these materiau-name
elements are defined in my table materiau
, hence the table oeuvre_materiau
in between comprised of only 2 elements, materiau_id
and oeuvre_id
.
But I have no clue on how to do that. I tried to add in my view an element from the table materiau
, but I just can't find how, and the only model called in my view is the Oeuvre
model.
Here is the Oeuvre
model class:
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; }
}
}
The materiau
model class:
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; }
}
}
The 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);
}
}
}
The Index
view :
@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>
The Create view :
@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")
}
The EDIT and DETAIL view are pretty similar.
So, I'm simply trying to add a dropdown box in my different view, which would be populated and populate the linking table oeuvre_materiau: