0

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);
        }
    }
}
3
  • 3
    Create a view model containing the properties you want to display/edit in the view. Commented Apr 20, 2017 at 22:30
  • I suggest having a connection like inside the company model have a Employee property. Then you can just return an Icollection of all employees in that Company or return a single Employee based on its Id. Also your Company model doesn't contain CompanyEmployee or Employee so how can you add them in the Include, as I am sure Companies is your DbSet for Company. Commented Apr 20, 2017 at 22:41
  • 1
    There are 10 different ways you can do it. Look at this article codeproject.com/Articles/1108855/… Commented Apr 20, 2017 at 22:50

2 Answers 2

1

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
Sign up to request clarification or add additional context in comments.

Comments

0

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

2 Comments

Hi Edward, I'm using VS 2017 which doesn't support your code.
Please explain how it doesn't work. My code is based out of VS 2015 community and works for ASPNetCore. Add the visual studio 2017 tag to the question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.