简体   繁体   中英

C# - Multiple models in a single view in MVC?

I'm trying to build a web app using Visual Studio 2017, Entity Framework Core. I want to combine 2 models into one view. I have 2 classes - Company & Employee that I want to combine. I want the employee info to be displayed alongside company info. What's the most elegant approach? I'm struggling quite a bit since this is my first web app.

Here's my base code:

Model:

using System;
using System.Collections.Generic;

namespace Company.Model
{
    public class Company
    {
        public int CompanyID { get; set; }
        public string CompanyWebsite { get; set; }
        public string CompanyPresident { get; set; }

    }

    public class Employee
    {
        public int EmployeeID { get; set; }
        public string Name { get; set; }
        public string Position { get; set; }
        public string Email { get; set; }
    }
}

This is my controller:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using CompanyApp.Data;
using CompanyApp.Model;

namespace CompanyApp.Controllers
{
    public class CompanyController : Controller
    {
        private readonly CompanyContext _context;

        public CompanyController(ManagementContext context)
        {
            _context = context;    
        }

        // GET: Companies
        public async Task<IActionResult> Index()
        {
            return View(await _context.Companies.ToListAsync());
        }

        // GET: Company/Details/5
        public async Task<IActionResult> Details(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var company = await _context.Companies
                .Include(s => s.CompanyEmployee)
                    .ThenInclude(e => e.Employee)
                    .AsNoTracking()
                .SingleOrDefaultAsync(m => m.CompanyID == id);
            if (company == null)
            {
                return NotFound();
            }

            return View(company);
        }

        // GET: Company/Create
        public IActionResult Create()
        {
            return View();
        }

        // POST: Company/Create
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Create([Bind("CompanyID,CompanyWebsite,CompanyPresident")] Company company)
        {
            if (ModelState.IsValid)
            {
                _context.Add(company);
                await _context.SaveChangesAsync();
                return RedirectToAction("Index");
            }
            return View(company);
        }

        // GET: Company/Edit/5
        public async Task<IActionResult> Edit(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var company = await _context.Companies.SingleOrDefaultAsync(m => m.CompanyID == id);
            if (company == null)
            {
                return NotFound();
            }
            return View(company);
        }

        // POST: Companies/Edit/5
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Edit(int id, [Bind("CompanyID,CompanyWebsite,CompanyPresident")] Company company)
        {
            if (id != company.CompanyID)
            {
                return NotFound();
            }

            if (ModelState.IsValid)
            {
                try
                {
                    _context.Update(company);
                    await _context.SaveChangesAsync();
                }
                catch (DbUpdateConcurrencyException)
                {
                    if (!CompanyExists(company.CompanyID))
                    {
                        return NotFound();
                    }
                    else
                    {
                        throw;
                    }
                }
                return RedirectToAction("Index");
            }
            return View(company);
        }

        // GET: Company/Delete/5
        public async Task<IActionResult> Delete(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var company = await _context.Companies
                .SingleOrDefaultAsync(m => m.CompanyID == id);
            if (company == null)
            {
                return NotFound();
            }

            return View(company);
        }

        // POST: Company/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> DeleteConfirmed(int id)
        {
            var company = await _context.Companies.SingleOrDefaultAsync(m => m.CompanyID == id);
            _context.Companies.Remove(company);
            await _context.SaveChangesAsync();
            return RedirectToAction("Index");
        }

        private bool CompanyExists(int id)
        {
            return _context.Companies.Any(e => e.CompanyID == id);
        }
    }
}

You should create new a model that include all property you need. For example as below:

public class CompanyModel
    {
        public int CompanyID { get; set; }
        public string CompanyWebsite { get; set; }
        public string CompanyPresident { get; set; }
        public Employee Employee { get; set; }
    }

var company = await _context.Companies
                .Include(s => s.CompanyEmployee)
                    .ThenInclude(e => e.Employee)
                    .AsNoTracking()
                .SingleOrDefaultAsync(m => m.CompanyID == id);

//Bind data from company into CompanyModel

A good example of these things can be found here I would suggest in Company model to add

 public Company(){ Employee = new HashSet<Employee>(); }
 public virtual ICollection<Employee> Employee (get;set);

and add to Employee

[ForeignKey("Company")]
public int CompanyId{get;set;}
public virtual Company Company { get; set; }

As well as having to add your binding in the DBContext class not the controller

public class CompanyContext : DbContext { 
    public DbSet<Company> Companies { get; set; }
    public DbSet<Employee> Employees  { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
       modelBuilder.Entity<Employee>(entity =>
        {entity.HasOne(d => d.Company)
                .WithMany(p => p.Employee)
                .HasForeignKey(d => d.CompanyId);
        });
    }
}

The code for the modelBuilder may need some changes, to work to your needs and models

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM