49 votes

Créer une liste déroulante pour MVC3 à l'aide de Entity Framework (modèle .edmx), de vues de rasoir et de insérer un enregistrement de base de données dans plusieurs tables

Après la lecture de 100 articles sur ici sur la façon de créer une Liste Déroulante dans MVC 3, avec Rasoir de points de Vue, je ne pouvais pas en trouver un qui colle parfaitement à mon cas. Donc après des Heures et des Heures de recherche pour la réponse, j'ai décidé de poster cette question pour voir si quelqu'un a la réponse ou peut m'aider. Je vous remercie à l'avance!!!!!

Situation: Je suis finalement en essayant de créer une Vue pour Ajouter un Employé à une Base de données.

Voici une image de la .EDMX Modèle que j'utilise (les tables qui seront utilisées par le create().):

enter image description here

Objectifs:

  1. Créer un Employé (j'ai le Créer.cshtml (fortement typé) avec une Vue Partielle de la StaffNotify Cases à cocher) {je suis en utilisant un @dans le modèle Informer Vue Partielle de la Vue de Créer pas sûr si c'est sûr??? @modèle ShadowVenue.Modèles.Employé & @modèle ShadowVenue.Modèles.StaffNotify)

  2. Créer une zone de liste Déroulante pour StaffTypeId (qui permet d'insérer le [StaffTypeId] valeur de la Table "StaffType" (qui a une relation 1 à plusieurs), mais le [Type] de la chaîne de valeur dans la liste déroulante)

  3. Créer une zone de liste Déroulante pour GenderId (qui permet d'insérer le [GenderId] valeur de la Table "Genres" (qui a une relation 1 à plusieurs), mais le [Genre] de la chaîne de valeur dans la liste déroulante)

  4. Insérer l'Enregistrement dans la base de données (j'ai le Personnel de Notifications dans une table séparée avec un 1 à 1 de relation sur le StaffId Clé Primaire)

Il me semble avoir de la difficulté avec le Contrôleur de code pour cela.

Je ne suis pas sûr si je devrais créer une Procédure Stockée dans le modèle EDMX, ou de venir avec un peu de requête ou de la méthode de la syntaxe, ne sais pas qui est le meilleur moyen.

Mon Premier Grand MVC3 Application à l'aide de Entity Framework Modèle.

Je vous remercie pour votre temps. J'apprécie vraiment les utilisateurs avertis sur ce site.

(si vous avez besoin de savoir tout de la Navigation Noms de Propriété afin d'aider avec la solution faites le moi savoir, je vais vous en fournir)

76voto

David Points 6057

Ne pas passer db modèles directement à votre point de vue. Vous êtes assez chanceux pour être en utilisant MVC, donc encapsuler l'aide de modèles de vue.

Créer un modèle de vue de la classe comme ceci:

public class EmployeeAddViewModel
{
    public Employee employee { get; set; }
    public Dictionary<int, string> staffTypes { get; set; }
    // really? a 1-to-many for genders
    public Dictionary<int, string> genderTypes { get; set; }

    public EmployeeAddViewModel() { }
    public EmployeeAddViewModel(int id)
    {
        employee = someEntityContext.Employees
            .Where(e => e.ID == id).SingleOrDefault();

        // instantiate your dictionaries

        foreach(var staffType in someEntityContext.StaffTypes)
        {
            staffTypes.Add(staffType.ID, staffType.Type);
        }

        // repeat similar loop for gender types
    }
}

Contrôleur:

[HttpGet]
public ActionResult Add()
{
    return View(new EmployeeAddViewModel());
}

[HttpPost]
public ActionResult Add(EmployeeAddViewModel vm)
{
    if(ModelState.IsValid)
    {
        Employee.Add(vm.Employee);
        return View("Index"); // or wherever you go after successful add
    }

    return View(vm);
}

Puis, enfin, à votre avis (que vous pouvez utiliser Visual Studio pour échafaudage d'abord), changer le type héréditaire à ShadowVenue.Modèles.EmployeeAddViewModel. Aussi, où les listes déroulantes aller, utilisez:

@Html.DropDownListFor(model => model.employee.staffTypeID,
    new SelectList(model.staffTypes, "ID", "Type"))

et de même pour le genre de liste déroulante

@Html.DropDownListFor(model => model.employee.genderID,
    new SelectList(model.genderTypes, "ID", "Gender"))

Mise à jour par les commentaires

Pour le sexe, vous pourriez aussi le faire si vous pouvez être sans le genderTypes dans le ci-dessus suggère modèle de vue (même si, à bien y penser, peut-être que je serais générer ce côté serveur dans le modèle de vue que IEnumerable). Donc, à la place de new SelectList... - dessous, vous devez utiliser votre IEnumerable.

@Html.DropDownListFor(model => model.employee.genderID,
    new SelectList(new SelectList()
    {
        new { ID = 1, Gender = "Male" },
        new { ID = 2, Gender = "Female" }
    }, "ID", "Gender"))

Enfin, une autre option est une table de Recherche. Fondamentalement, vous gardez les paires clé-valeur associée à une Recherche de type. Un exemple d'un type peut être le sexe, tandis qu'un autre peut être l'Etat, etc. J'aime la structure de la mine comme ceci:

ID | LookupType | LookupKey | LookupValue | LookupDescription | Active
1  | Gender     | 1         | Male        | male gender       | 1
2  | State      | 50        | Hawaii      | 50th state        | 1
3  | Gender     | 2         | Female      | female gender     | 1
4  | State      | 49        | Alaska      | 49th state        | 1
5  | OrderType  | 1         | Web         | online order      | 1

J'aime l'utilisation de ces tableaux lorsqu'un jeu de données ne change pas très souvent, mais doit encore être énumérés de temps à autre.

Espérons que cette aide!

23voto

nttakr Points 964

Eh bien, en fait, je vais avoir à dire que David est à droite avec sa solution, mais il y a certains sujets me déranger:

  1. Vous ne devez jamais envoyer votre modèle à l'affichage => C'est correct
  2. Si vous créez un ViewModel, et inclure le Modèle en tant que membre de l' ViewModel, alors vous avez effectivement envoyé votre modèle à l'Affichage => c'est MAUVAIS
  3. À l'aide de dictionnaires pour envoyer les options de la vue => pas bon style

Alors, comment pouvez-vous créer un meilleur couplage?

Je voudrais utiliser un outil comme AutoMapper ou ValueInjecter à la carte entre ViewModel et le Modèle. AutoMapper ne semble pas disposer de la meilleure syntaxe et se sentent à elle, mais la version actuelle manque un très sévère sujet: Il n'est pas en mesure d'effectuer la cartographie de l' ViewModel pour le Modèle (dans certaines circonstances, comme l'aplatissement, etc., mais c'est hors sujet) Donc, à l'heure actuelle, je préfère utiliser l' ValueInjecter.

Ainsi, vous créez un ViewModel avec les champs dont vous avez besoin dans la vue. Vous ajoutez le SelectList éléments dont vous avez besoin, comme les recherches. Et vous ajouter comme SelectLists déjà. De sorte que vous pouvez requête à partir d'une LINQ activé sourc, sélectionnez l'ID et le champ de texte et l'enregistrer comme une selectlist: Vous gain que vous n'avez pas à créer un nouveau type (dictionnaire) que de recherche et vous venez de passer l' new SelectList à partir de la vue du contrôleur.

  // StaffTypes is an IEnumerable<StaffType> from dbContext
  // viewModel is the viewModel initialized to copy content of Model Employee  
  // viewModel.StaffTypes is of type SelectList

  viewModel.StaffTypes =
    new SelectList(
        StaffTypes.OrderBy( item => item.Name )
        "StaffTypeID",
        "Type",
        viewModel.StaffTypeID
    );

Dans la vue, vous avez juste à appeler

@Html.DropDownListFor( model => mode.StaffTypeID, model.StaffTypes )

De retour dans le poste de l'élément de votre méthode dans le contrôleur, vous devez prendre un paramètre de type de votre ViewModel. Vous vérifiez ensuite pour validation. Si la validation échoue, vous ne devez pas oublier de re-remplir le viewModel.StaffTypes SelectList, parce que ce point sera nulle à l'entrée de la poste de la fonction. Donc j'ai tendance à avoir ceux de la population choses séparées dans une fonction. Vous juste de retour d'appel return new View(viewModel) si quelque chose est incorrect. Les erreurs de Validation trouvé par MVC3 sera automatiquement affichée dans la vue.

Si vous avez votre propre code de validation vous pouvez ajouter des erreurs de validation par la spécification du domaine auquel ils appartiennent. Vérifier la documentation en ModelState pour obtenir des informations sur que.

Si l' viewModel est valide, vous devez effectuer l'étape suivante:

Si c'est une création d'un nouvel élément, vous devez remplir un modèle de l' viewModel (le mieux est ValueInjecter). Ensuite, vous pouvez l'ajouter à l'EF de la collecte de ce type et de valider les modifications.

Si vous avez une mise à jour, vous obtenez le courant db élément premier dans un modèle. Ensuite, vous pouvez copier les valeurs de l' viewModel vers le modèle (en utilisant à nouveau ValueInjecter vous permet de vous faire très rapide). Après cela, vous pouvez SaveChanges et sont effectués.

N'hésitez pas à demander si quelque chose n'est pas clair.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X