Je travaille avec ASP.NET MVC 4 et Entity Framework et je cherchais un moyen de faire beaucoup de relation et de cases à cocher de mon db pour un Créer/Modifier le contrôleur et afficher, j'ai trouvé la réponse avec réponse @Slauma pour créer dans MVC 4 - Many-to-Many relation and checkboxes mais, j'aimerais vraiment voir comment cela s'étend à la fonctionnalité Modifier et supprimer ainsi que d'autres partenaires dans cette solution. Quelqu'un pourrait-il montrer comment je remplirais le ClassificationSelectViewModel dans la méthode Edit controller pour obtenir les valeurs "checked" et "unchecked"? C'est une question de Matt Flowers qui va résoudre le mien aussi.MVC 4 Edit Contrôleur/Voir plusieurs à plusieurs relations et cases à cocher
Répondre
Ce qui suit est une continuation de this answer qui décrit Create
actions GET et POST pour un modèle avec plusieurs à plusieurs entre entités Subscription
et Company.
Voici la procédure pour les Edit
actions que je le ferais (sauf que je ne serait probablement pas mettre tout le code EF dans les actions du contrôleur, mais l'extraire dans des méthodes d'extension et de service):
le CompanySelectViewModel
reste inchangé:
public class CompanySelectViewModel
{
public int CompanyId { get; set; }
public string Name { get; set; }
public bool IsSelected { get; set; }
}
le SubscriptionEditViewModel
est le SubscriptionCreateViewModel
ainsi que la 'propriété clé de:
public class SubscriptionEditViewModel
{
public int Id { get; set; }
public int Amount { get; set; }
public IEnumerable<CompanySelectViewModel> Companies { get; set; }
}
L'action GET
pourrait ressembler à ceci:
public ActionResult Edit(int id)
{
// Load the subscription with the requested id from the DB
// together with its current related companies (only their Ids)
var data = _context.Subscriptions
.Where(s => s.SubscriptionId == id)
.Select(s => new
{
ViewModel = new SubscriptionEditViewModel
{
Id = s.SubscriptionId
Amount = s.Amount
},
CompanyIds = s.Companies.Select(c => c.CompanyId)
})
.SingleOrDefault();
if (data == null)
return HttpNotFound();
// Load all companies from the DB
data.ViewModel.Companies = _context.Companies
.Select(c => new CompanySelectViewModel
{
CompanyId = c.CompanyId,
Name = c.Name
})
.ToList();
// Set IsSelected flag: true (= checkbox checked) if the company
// is already related with the subscription; false, if not
foreach (var c in data.ViewModel.Companies)
c.IsSelected = data.CompanyIds.Contains(c.CompanyId);
return View(data.ViewModel);
}
La vue Edit
est la vue Create
plus un champ caché pour les Subscription
' Subscription
s propriété clé Id
:
@model SubscriptionEditViewModel
@using (Html.BeginForm()) {
@Html.HiddenFor(model => model.Id)
@Html.EditorFor(model => model.Amount)
@Html.EditorFor(model => model.Companies)
<input type="submit" value="Save changes" />
@Html.ActionLink("Cancel", "Index")
}
L'éditeur mplate pour sélectionner une entreprise reste inchangée:
@model CompanySelectViewModel
@Html.HiddenFor(model => model.CompanyId)
@Html.HiddenFor(model => model.Name)
@Html.LabelFor(model => model.IsSelected, Model.Name)
@Html.EditorFor(model => model.IsSelected)
Et l'action POST pourrait ressembler à ceci:
[HttpPost]
public ActionResult Edit(SubscriptionEditViewModel viewModel)
{
if (ModelState.IsValid)
{
var subscription = _context.Subscriptions.Include(s => s.Companies)
.SingleOrDefault(s => s.SubscriptionId == viewModel.Id);
if (subscription != null)
{
// Update scalar properties like "Amount"
subscription.Amount = viewModel.Amount;
// or more generic for multiple scalar properties
// _context.Entry(subscription).CurrentValues.SetValues(viewModel);
// But this will work only if you use the same key property name
// in ViewModel and entity
foreach (var company in viewModel.Companies)
{
if (company.IsSelected)
{
if (!subscription.Companies.Any(
c => c.CompanyId == company.CompanyId))
{
// if company is selected but not yet
// related in DB, add relationship
var addedCompany = new Company
{ CompanyId = company.CompanyId };
_context.Companies.Attach(addedCompany);
subscription.Companies.Add(addedCompany);
}
}
else
{
var removedCompany = subscription.Companies
.SingleOrDefault(c => c.CompanyId == company.CompanyId);
if (removedCompany != null)
// if company is not selected but currently
// related in DB, remove relationship
subscription.Companies.Remove(removedCompany);
}
}
_context.SaveChanges();
}
return RedirectToAction("Index");
}
return View(viewModel);
}
Les Delete
actions sont moins difficiles. Dans l'action GET
vous pouvez charger quelques propriétés de l'abonnement pour afficher sur la vue de la confirmation de suppression:
public ActionResult Delete(int id)
{
// Load subscription with given id from DB
// and populate a `SubscriptionDeleteViewModel`.
// It does not need to contain the related companies
return View(viewModel);
}
Et dans l'action POST
que vous chargez l'entité et le supprimer ensuite. Il n'y a pas besoin d'inclure les entreprises parce que dans un grand nombre à plusieurs rapports (généralement) suppression en cascade sur la table de lien est activé afin que la base de données se chargera de supprimer les entrées de lien avec le parent Subscription
:
[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirm(int id)
{
var subscription = _context.Subscriptions.Find(id);
if (subscription != null)
_context.Subscriptions.Remove(subscription);
return RedirectToAction("Index");
}
très bonne réponse! J'ai dû faire un petit changement cependant. J'ai dû changer data.ViewModel.Companies.ForEach ( c => {c.IsSelected = data.CompanyIds.Contains (c.CompanyId);}); à foreach (var c dans data.ViewModel.Entreprises) { c.IsSelected = data.CompanyIds.Contains (c.CompanyID); } (Désolé pour le mauvais format de commentaire.) –
@MattFlowers: Ah, c'est vrai, j'ai corrigé ça. Merci! – Slauma
@Slauma Hey question stupide ce que le code semble l ike sur la vue (avec des cases à cocher ... +1 très utile ce que je veux dire est que lorsque j'utilise 'CompanySelectViewModel' à mon avis, je reçois ** Erreur **' l'élément de modèle passé dans le dictionnaire est de type' car il attend 'SubscriptionEditViewModel' –
- 1. ASP.NET MVC - Utilisation de cases à cocher pour mettre à jour plusieurs à plusieurs relations
- 2. Laravel 4 soumettant plusieurs cases à cocher
- 3. Plusieurs cases à cocher dans mvc 3
- 4. ASP.NET MVC plusieurs cases à cocher
- 5. A plusieurs cases à cocher ne sauvera pas Rails 4
- 6. ajax et plusieurs cases à cocher
- 7. MVC + Entités Framework: plusieurs à plusieurs relations
- 8. jquery plusieurs cases à cocher tableau
- 9. symfony2 formes et plusieurs-à-plusieurs relations
- 10. plusieurs cases à cocher en utilisant jquery
- 11. Pylônes/Formencode avec plusieurs cases à cocher
- 12. Désactiver plusieurs cases à cocher avec javascript
- 13. Relations ORM et plusieurs-à-plusieurs
- 14. Jquery sélectionner plusieurs cases à cocher
- 15. Forcer une ou plusieurs cases à cocher
- 16. iOS - Gestion de plusieurs cases à cocher
- 17. un formulaire avec plusieurs cases à cocher
- 18. plusieurs cases à cocher listview dans CompactFramework
- 19. Plusieurs lignes et cases à cocher colonne php
- 20. Plusieurs à plusieurs relations
- 21. Plusieurs à plusieurs relations | Supprimer
- 22. Jquery Plusieurs cases à cocher avec plusieurs pages
- 23. ExtJs 4 combobox avec cases à cocher
- 24. Comment enregistrer plusieurs cases à cocher (jQuery et PHP)?
- 25. Entity Framework 4 - comment supprimer des relations plusieurs-à-plusieurs
- 26. ASP.net MVC et cases à cocher
- 27. Relations plusieurs-à-plusieurs et clés étrangères
- 28. SolrNet et plusieurs à plusieurs relations
- 29. ADO.NET DataRelations et relations plusieurs-à-plusieurs
- 30. Plusieurs cases à cocher cocher comme dans Gmail
Pouvez-vous nous montrer ce que vous avez déjà fait? – Jack
@Jack: Fondamentalement, le schéma create model/view/controller du lien, avec quelques petites exceptions et ce dont j'ai besoin est la méthode Edit, je suppose que je ne peux pas ajouter autre chose que vous ne pouvez pas voir là-bas – JamesT