当当前记录没有元素时,MVC dbContext查找父记录 [英] MVC dbContext find parent record when current record has no elements

查看:85
本文介绍了当当前记录没有元素时,MVC dbContext查找父记录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是MVC/C#初学者,所以请放轻松.

I'm a MVC/C# beginner so go easy.

我有一个现有的数据库,其中客户有零个或多个项目.我已经从ADODB实体数据模型和dbContext代码生成器构建了一个ASP.Net项目.

I have an existing database where a Customer has zero or many Projects. I've built an ASP.Net project from ADODB Entity data model and dbContext code generators.

我有一个客户:Joe Bloggs(ID = 7).我单击表单中Joe Bloggs的项目"链接以查看他的项目.他没有.我想为他创建一个项目,所以我在项目控制器上调用创建"操作.

I have a customer: Joe Bloggs (ID=7). I click on the 'Projects' link for Joe Bloggs in my form to see his projects. He doesn't have any. I want to create a project for him so I call the Create action on the project controller.

出于以下三个原因,我需要将Joe Bloggs ID传递给创建"操作(这可能不是必需的-如果需要的话请赐教)

I need to pass Joe Bloggs ID to the Create action for three reasons (which may not be necessary - please enlighten me if need be)

  1. 因为这是Joe Bloggs的项目,所以我需要将ID = 7传递给控制器​​,以便在为创建视图生成模型数据时为他设置默认的Customer ID

  1. Because this is a project for Joe Bloggs I need to pass ID=7 into the controller so I can set the default Customer ID for him when generating the model data for the create view

当我点击创建"视图上的取消"按钮时,我想回到基于Joe Blogs的项目的原始筛选视图

When I hit the Cancel button on the Create view, I want to go back to the originally filtered view of projects based on Joe Blogs

当我单击保存时,我想回到基于Joe Bloggs的项目的原始筛选视图.

When I hit save I want to got back to the originally filtered view of projects based on Joe Bloggs.

无论如何,如果我有一个或多个Joe Bloggs项目,那么我可以使用下面的这个怪物从视图中的模型数据访问他的id:

Anyway if I do have one or more projects for Joe Bloggs then I can use this monster below to access his id from the model data within the view:

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

这是问题所在:如果他没有任何项目,Model.First()不会返回任何内容,所以我找不到父" Customer_ID记录.

Here is the issue: if he doesn't have any projects, Model.First() doesn't return anything so I can't find the 'parent' Customer_ID record.

我使用dbContext生成了模型类(这是数据优先的开发).某些事情告诉我,我可以扩展这些类或创建一个新类,以允许上述情况.

I used dbContext to generate the model classes (this is a data-first development). Something tells me I could extend these classes or create a new class to allow for the case above.

我当前的解决方法是使用ViewBag从查看器>控制器传递各种ID和字符串,就像土豆一样,但这意味着如果深入三个(Customer> Proejct> Task),我想在任务,我已经通过了两次.闻起来.

My current workaround is to use ViewBag to pass the various id's and strings from viewer > controller like a hot potato but this means if get three deep (Customer > Proejct > Task), and I want to display the customer name on the task, I've passed it twice. It smells.

我注意到,项目索引视图中的下拉菜单其中有客户.这是我的代码:

I notice that the drop down in the Project Index view has the Customer in it. Here is my code for that:

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

我也许可以从那里砍掉它,但实际上我希望能够从可能有两三层之遥的班级上移下来,并且与该下拉菜单相去甚远

I might be able to hack it out of there but really I want to be able to traverse up from a class which might be two or three deep and far removed from this drop down

这是从dbContext生成的简化的Customer和CustomerProject类

Here is an abridged Customer and CustomerProject class generated from 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; }
}

我肯定有一个明显的解决方案,但是我的优势是数据库和VB6,而不是C#

I'm sure there is an obvious solution but my strength is in databases and VB6, not C#

在Mystere Man的建议下,我建立了一个ViewModel类,但遇到了一些麻烦:

At Mystere Man's suggestion I have built a ViewModel class, but I'm having a little trouble:

这是我的模型类文件中的内容(据我了解,这只是现有项目实体的包装):

Here is what's in my model class file (as I understand it this is just a wrapper around the the existing project entity):

namespace zzz.Models
{
    using System;
    using System.Collections.Generic;

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

这是我控制器的Index操作中的内容(我刚刚将现有的Project集合添加到了新的ViewModel类中):

Here's whats in the Index action of my controller (I havejust added my existing Project collection to the new ViewModel class):

    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);
    }

这是我的观点的一部分(我尝试遍历ViewModel类中的Project集合):

Here's an extract from my view (I have tried to iterate through the Project collection within the ViewModel class):

@model IEnumerable<BistechPortal.Models.ProjectsViewModel>

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

当我运行Index动作时,在foreach行上我得到:

When I run the Index action, on the foreach line I get:

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

请翻译-为什么它无法在ViewModel中找到我的"CustomerProjects"集合?

Please translate - why can't it find my 'CustomerProjects' collection inside my ViewModel?

推荐答案

这就是为什么您不应该将实体对象直接传递给视图的原因.在大多数情况下,视图需要比已定义实体提供的信息更多(或不同的信息).

This is why you should not pass entity objects directly to the view. In most cases, the view needs more information (or different information) than what the defined entity provides.

这就是为什么存在视图模型的原因.您将创建一个包含Customer_ID和项目(以及您需要的任何其他数据)的视图模型.然后,即使用户没有项目,也可以访问Customer_ID.

This is why View Models exist. You would create a View Model that contains the Customer_ID and the Projects (and any other data you need). Then, you can access the Customer_ID even if the user has no projects.

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

然后将这个新对象传递给视图.

Then you pass this new object to your view.

(由OP添加:)

要将这个对象传递给您的视图,您需要告诉该视图,它不再接受CustomerProjects,类型的数据(这花了我三个小时的时间),不再获取无数"数据.

To pass this object to your view you need to tell the view that it is no longer accepting data of type CustomerProjects, and (this took me three hours to work out) that it is no longer getting 'enumerable' data.

因此,您认为更改

@model IEnumerable<Portal.Models.CustomerProjects>

@model Portal.Models.ProjectsViewModel

在您的视图中,您现在还想遍历Model.CustomerProject,因此进行更改

Also in your view you now want to iterate over Model.CustomerProject, so change

@foreach (var item in Model)

@foreach (var item in Model.CustomerProjects)

这篇关于当当前记录没有元素时,MVC dbContext查找父记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆