MVC两个控制器One View

时间:2015-11-10 14:55:02

标签: c# sql-server asp.net-mvc visual-studio-2013

我正在尝试在连接两个控制器并传入视图的现有控制器中有一个详细信息视图,但到目前为止我尝试的所有内容都没有用。我有4个数据模型,我想要的是使用其中2个公司和员工。因此,当我选择特定公司的详细信息时,它将在同一视图中返回与该公司关联的所有员工。

HRDataModel类

  public partial class HRDataModel : DbContext
{
    public HRDataModel()
        : base("name=HRDataModel")
    {
    }
    public virtual DbSet<Company> Companies{ get; set; }
    public virtual DbSet<Attribs> Attribs{ get; set; }
    public virtual DbSet<Staff> Staffs { get; set; }
    ....

公司数据模型

[Table("Company")]
public partial class Company
{
    public Company()
    {
        Staffs = new HashSet<Staff>();
    }
    public virtual ICollection<Staff> Staffs { get; set; }
    public int companyId{ get; set; }

    [Required]
    [StringLength(10)]
    public string companyName{ get; set; }
    .....

员工数据模型

public partial class Staff
{
    public Staff()
    {
        Skills = new HashSet<Skill>();
    }
    public virtual Company Company{ get; set; }

    public virtual ICollection<Skill> Skills { get; set; }

    public int staffId { get; set; }
    .........

我正在尝试在CompanyController中获取我的详细信息方法,以显示数据库中所有活动公司的详细信息以及与该公司相关的所有员工

[Route("Company/Staff/1}")]
public ActionResult Details(int id)
{
    Company co = db.Companies.Find(id); 
    ...How to implement????           
    return View(bu);
}

如果有人能指出我正确的方向那将是伟大的。我已经尝试过并尝试过但无法正常工作?

4 个答案:

答案 0 :(得分:1)

嗨@stackface你没有传递两个控制器来获取两个视图,你要做的就是创建一个View Model,它实际上是多个模型的容器,并从控制器传递到视图中。

E.g。模型1,模型2,模型N都是必需的,因此您有一个类,并且在该类中它具有​​由Model1,Model2和Model3组成的属性,以便您传入具有所有所需模型的类。

E.g。

public class Company{...}

public class Staff{...}

public class ViewModel{
public Company Company {get;set;}
public List<Staff> Staff{get;set;}
}

controller:
{
var viewModel = new ViewModel();
viewModel.Company = db.Companies.FirstOrDefault(x => x.id == companyId);
viewModel.Staff = db.Staff.Where(x => x.CompanyId == campanyId).ToList() //or whatever your properties are called.

Return View(viewModel);
}

更新您的视图以采用ViewModel类型。

答案 1 :(得分:1)

您需要将包含公司信息和员工详细信息的数据结构传递给您的视图。您可以传递现有的Comapny实体类来执行此操作。但问题是,它使您的剃刀视图与ORM生成的实体紧密耦合。如果明天将数据访问层切换为其他内容,该怎么办?所以这个解决方案并不好。

因此,您应该使用视图模型(一个简单的POCO类),它具有您需要在视图中呈现的属性。然后在您的action方法中从db读取您的实体,将其映射到vie wmodel实例并发送它。

创建这样的视图模型。

public class CompanyInfo
{
  public int Id {set;get;}
  public string Name {set;get;}
  public List<StaffItem> Staffs {set;get;}
  public CompanyInfo()
  {
     this.Staffs = new List<StaffItem>();
  }
}
public class StaffItem
{
  public int Id {set;get;}
  public string Name {set;get;}
}

在您的操作方法中,阅读公司实体并将其映射到视图模型

public ActionResult Details(int id)
{
    var vm = new ComapnyInfo();
    var company = db.Companies
             .Include(r => c.Staffs)
             .FirstOrDefault(x => x.companyId==id); 

    if(co!=null)
    {
       //Map the property values now
       vm.Name = co.companyName;
       vm.Id = co.companyId;
       if(co.Staffs!=null)
       {
         vm.Staffs = co.Staffs.Select(f=> new StaffItem {
                              Id=f.staffId,
                              Name = f.staffName}).ToList();
       }
    }       
    return View(vm);
}

现在您的视图应绑定到CompanyInfo视图模型

@model YourNamespace.CompanyInfo
<h2>@Model.Name</h2>
<h3>Staffs</h3>
@foreach(var staff in ModelStaffs)
{
  <p>@staff.Name</p>
}

如果您不喜欢手动映射,可以考虑使用像Automapper这样的映射库。

答案 2 :(得分:1)

由于公司包括员工,您可以使用include方法包含相关实体。

var company = db.Companies.Include(c => c.Staffs).FirstOrDefault(x => x.id == companyId);
return View(company);

在你看来:

@foreach(var staff in Model.Staffs) { ... }

答案 3 :(得分:0)

您还可以通过调用返回部分视图的控制器操作来组合视图。

优点是您可以重复使用部分视图及其操作,例如在不同页面上显示具有相同布局的公司详细信息。这提高了一致性和可维护性。

缺点是您失去了灵活性:如果某个页面需要不同的布局,您应该创建一个新视图。性能可能也会降低,因为您使用许多小型操作而不是单个大型操作来使用后端。

用于显示公司和员工详细信息的组合viewmodel只需要知道如何访问所需的数据:

public class CompanyAndStaffDetailsViewModel {
    public long CompanyId { get; set; }
    public long StaffId { get; set; }
}

以下操作呈现组合视图:

public ActionResult Details(long companyId, long staffId) {
    var viewModel = new CompanyAndStaffDetailsViewModel {
        CompanyId = companyId,
        StaffId = staffId
    };
    return View("Details", viewModel);
}

“详细信息”视图通过调用动作来呈现部分视图来组成用例:

@model CompanyAndStaffDetailsViewModel 
@Html.Action("CompanyInfoPartial", "Company", new { companyId = Model.CompanyId })
@Html.Action("StaffInfoPartial", "Staff", new { staffId = Model.StaffId })

“公司”控制器提供可重复使用的操作以呈现公司详细信息:

 public ActionResult CompanyInfoPartial(long companyId) {
       Company co = db.Companies.Find(companyId);
       var model = Mapper.Map<CompanyViewModel>(co); // map persistable entity to ViewModel
       return PartialView("_CompanyInfoPartial", model);
 }

然后parital View _CompanyInfoParital.cshtml只需要处理存储在CompanyViewModel中的公司信息,而对员工一无所知:

@model CompanyViewModel
@Html.DisplayFor(m => m.CompanyName)
// etc ...

StaffInfoPartial操作的想法与CompanyInfoPartial相同。