Question

Je suis un débutant mvc / c # alors allez facilement.

J'ai une base de données existante où un client a zéro ou de nombreux projets. J'ai construit un projet ASP.NET à partir du modèle de données de données d'entité Adodb et des générateurs de code DBContext.

J'ai un client: Joe Bloggs (ID= 7). Je clique sur le lien "Projets" pour Joe Bloggs dans mon formulaire pour voir ses projets. Il n'en a pas. Je veux créer un projet pour lui, donc j'appelle l'action Créer sur le contrôleur de projet.

J'ai besoin de passer à Joe Bloggs ID à l'action Créer pour trois raisons (ce qui pourrait ne pas être nécessaire - s'il vous plaît éclairer si besoin d'être)

  1. Parce qu'il s'agit d'un projet de Joe Bloggs, je dois passer ID= 7 dans le contrôleur afin que je puisse définir l'ID client par défaut pour lui lors de la génération des données de modèle pour la vue Create View

  2. Lorsque je touche le bouton Annuler de la vue Créer, je souhaite revenir à la vue filtrée à l'origine des projets basés sur Joe Blogs

  3. Lorsque je touche Save, je veux revenir à la vue filtrée initialement des projets basée sur Joe Bloggs.

    Quoi qu'il en soit si je do avez un ou plusieurs projets pour Joe Bloggs, alors je peux utiliser ce monstre ci-dessous pour accéder à son identifiant à partir des données de modèle dans la vue:

    <input type="button" title = "New Project" value="New Project" onclick="location.href='@Url.Action("Create", new { id = Model.First().Customer_ID })'" />
    

    Voici le problème: s'il n'a pas de projets, Model.First () ne renvoie rien, donc je ne trouve pas le dossier client «parent».

    J'ai utilisé DBContext pour générer les classes de modèle (il s'agit d'un développement de données - Premier développement). Quelque chose me dit que je pourrais étendre ces classes ou créer une nouvelle classe pour permettre l'affaire ci-dessus.

    Ma solution de contournement actuelle consiste à utiliser ViewBag pour transmettre les différents identifiants et chaînes de Viewer> Controller comme une pomme de terre chaude, mais cela signifie que si vous obtenez trois profondes (client> proejCt> tâche) et je souhaite afficher le nom du client sur le Tâche, je l'ai passé deux fois. Ça sent.

    Je remarque que la liste déroulante dans la vue Index du projet a le client de celui-ci . Voici mon code pour cela:

    @Html.DropDownList("Customer_ID", null, "Select a Customer to Filter", new { @onchange = "this.form.submit();" })
    

    Je pourrais être capable de le pirater de là, mais je veux vraiment pouvoir traverser d'une classe qui pourrait être deux ou trois profondes et éloignée de cette descente

    Voici un classement client abrégé et CustomerProject généré de DBContext

    public partial class Customer
    {
        public Customer()
        {
            this.Tasks = new HashSet<Task>();
            this.CustomerProjects = new HashSet<CustomerProject>();
        }
    
        public int Customer_ID { get; set; }
        public string Customer_Name { get; set; }
    
        public virtual ICollection<CustomerProject> CustomerProjects { get; set; }
    }
    
    public partial class CustomerProject
    {
        public CustomerProject()
        {
            this.Tasks = new HashSet<Task>();
            this.CustomerProjectTasks = new HashSet<CustomerProjectTask>();
        }
    
        public int CustomerProject_ID { get; set; }
        public int Customer_ID { get; set; }
        public string Project_Name { get; set; }
    
        public virtual ICollection<Task> Tasks { get; set; }
        public virtual Customer Customer { get; set; }
        public virtual ICollection<CustomerProjectTask> CustomerProjectTasks { get; set; }
    }
    

    Je suis sûr qu'il y a une solution évidente, mais ma force est dans les bases de données et VB6, pas C #

    à la suggestion de Mystere Man j'ai construit une classe de menuLoDel, mais j'ai un peu de problèmes:

    Voici ce qui est dans mon fichier de classe modèle (comme je le comprends, il s'agit simplement d'une enveloppe autour de l'entité de projet existante):

    namespace zzz.Models
    {
        using System;
        using System.Collections.Generic;
    
        public class ProjectsViewModel
        {
            public int Customer_ID { get; set; }
            public ICollection<CustomerProject> CustomerProjects;
        }
    }
    

    Voici ce qui est dans l'action d'index de mon contrôleur (je n'ai pas ajouté ma collection de projets existante à la nouvelle classe de menuLodel):

        public ViewResult Index(int pCustomer_ID = 0, string pProjectName_Filter = "")
        {
    
            // Set up drop down
            ViewBag.Customer_ID = new SelectList(db.Customers.OrderBy(x => x.Customer_Name), "Customer_ID", "Customer_Name");
            //ViewBag.Selected_Customer_ID = Customer_ID;
    
            // If no parameters entered, show nothing
            // Otherwise optionally filter each parameter
            var projects = from p in db.CustomerProjects
                orderby p.Active, p.Project_Order
                where
                (p.Project_Name.Contains(pProjectName_Filter) || pProjectName_Filter.Equals("")) &&
                (p.Customer_ID == pCustomer_ID || pCustomer_ID.Equals(0)) &&
                !(pCustomer_ID.Equals(0) && pProjectName_Filter.Equals(""))
                select p;
    
    
            var customerprojects = new ProjectsViewModel
            {
                Customer_ID = pCustomer_ID,
                CustomerProjects = projects.ToList()
            };
    
    
            return View(customerprojects);
        }
    

    Voici un extrait de mon point de vue (j'ai essayé de parcourir la collection de projets dans la classe ViewModel):

    @model IEnumerable<BistechPortal.Models.ProjectsViewModel>
    
    <table>
    @foreach (var item in Model.CustomerProjects)
    {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Project_Name)
        </td>
    </tr>
    }
    </table>
    

    Quand j'exécute l'action d'index, sur la ligne de Forach, je reçois:

    'System.Collections.Generic.IEnumerable<zzzzPortal.Models.ProjectsViewModel>' does not contain a definition for 'CustomerProjects' "
    

    Veuillez traduire - pourquoi ne peut-il pas trouver ma collection «Customprojects» à l'intérieur de My ViewModel?

Était-ce utile?

La solution

C'est pourquoi vous ne devez pas passer directement des objets d'entité à la vue.Dans la plupart des cas, la vue a besoin de plus d'informations (ou d'informations différentes) que ce que l'entité définie fournit.

C'est pourquoi les modèles d'affichage existent.Vous créeriez un modèle de vue contenant le Customer_ID et les projets (et toutes les autres données dont vous avez besoin).Ensuite, vous pouvez accéder au client_id même si l'utilisateur n'a pas de projets.

public class ProjectsViewModel {
     public int Customer_ID {get;set;}
     public List<CustomerProject> CustomerProjects;
}

Ensuite, vous passez ce nouvel objet à votre vue.

(ajouté par OP :)

Pour transmettre cet objet à votre vue, vous devez dire que cela n'accepte plus les données de type CustomersProjects, et (cela m'a pris trois heures pour travailler) que ce n'est plusobtenir des données «énumérables».

donc à votre vue Changer

@model IEnumerable<Portal.Models.CustomerProjects>

à

@model Portal.Models.ProjectsViewModel

Aussi à votre vue, vous voulez maintenant itérer sur Model.CustomerProject, alors changez

@foreach (var item in Model)

à

@foreach (var item in Model.CustomerProjects)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top