0

I am new to MVC and Entity Framework and have decided to use the Code First approach using ViewModels.

I have tried many different tutorials but no one that i've tried has used Code First in EF Core with ViewModels.

My Models

public class Intermediary
{
 public int IntermediaryID { get; set; }
 public string RegisteredName { get; set; }
 public string TradingName { get; set; }
 public int Registration { get; set; }
 public int VATNumber { get; set; }
 public int FSPNumber { get; set; }
 public DateTime CreatedDate { get; set; }
 public string CreatedBy { get; set; }
 public ICollection<Branch> Branches { get; set; }
}
public class Branch
{
 public int BranchID { get; set; }
 public string Name { get; set; }
 public DateTime CreatedDate { get; set; }
 public string CreatedBy { get; set; }
 public Intermediary Intermediary { get; set; }
}

My ViewModel

public class IntermediariesViewModel
{
 public int ID { get; set; }
 public Intermediary Intermediary { get; set; }
 public virtual ICollection<Branch> Branches { get; set; }
}

My Data Context Class

public class BizDevHubContext : DbContext
{
 public BizDevHubContext(DbContextOptions<BizDevHubContext> options) : base(options)
 {
 }
 public DbSet<Intermediary> Intermediaries { get; set; }
 public DbSet<Branch> Branches { get; set; }
 protected override void OnModelCreating(ModelBuilder modelBuilder)
 {
 modelBuilder.Entity<Intermediary>().ToTable("Intermediary");
 modelBuilder.Entity<Branch>().ToTable("Branch");
 }
}

My Initializer Class

public static class DbInitializer
{
 public static void Initialize(BizDevHubContext context)
 {
 context.Database.EnsureCreated();
 if (context.Intermediaries.Any())
 {
 return; // DB has been seeded
 }
 var intermediaries = new Intermediary[]
 {
 new Intermediary{RegisteredName="Carson",TradingName="Alexander",CreatedDate=DateTime.Now,CreatedBy="System"},
 new Intermediary{RegisteredName="Meredith",TradingName="Alonso",CreatedDate=DateTime.Now,CreatedBy="System"},
 new Intermediary{RegisteredName="Arturo",TradingName="Anand",CreatedDate=DateTime.Now,CreatedBy="System"},
 new Intermediary{RegisteredName="Gytis",TradingName="Barzdukas",CreatedDate=DateTime.Now,CreatedBy="System"},
 new Intermediary{RegisteredName="Yan",TradingName="Li",CreatedDate=DateTime.Now,CreatedBy="System"},
 new Intermediary{RegisteredName="Peggy",TradingName="Justice",CreatedDate=DateTime.Now,CreatedBy="System"},
 new Intermediary{RegisteredName="Laura",TradingName="Norman",CreatedDate=DateTime.Now,CreatedBy="System"},
 new Intermediary{RegisteredName="Nino",TradingName="Olivetto",CreatedDate=DateTime.Now}
 };
 foreach (Intermediary i in intermediaries)
 {
 context.Intermediaries.Add(i);
 }
 context.SaveChanges();
 var branches = new Branch[]
 {
 new Branch{Name="Bloemfontein",CreatedDate=DateTime.Now,CreatedBy="System"},
 new Branch{Name="Cape Town",CreatedDate=DateTime.Now,CreatedBy="System"},
 new Branch{Name="Durban",CreatedDate=DateTime.Now,CreatedBy="System"},
 new Branch{Name="Nelspruit",CreatedDate=DateTime.Now,CreatedBy="System"},
 new Branch{Name="Johannesburg",CreatedDate=DateTime.Now,CreatedBy="System"},
 new Branch{Name="Port Shepstone",CreatedDate=DateTime.Now,CreatedBy="System"},
 new Branch{Name="Pretoria",CreatedDate=DateTime.Now,CreatedBy="System"}
 };
 foreach (Branch b in branches)
 {
 context.Branches.Add(b);
 }
 context.SaveChanges();
 }
}

This all seems to work fine and the database gets created ok, but I am stuck now trying to create the Controller and Views

I managed to do it with a single model but cannot seem to get it right putting the entire viewmodel.

My Controller

using BizDevHub.ViewModels;
public async Task<IActionResult> Index()
{
 return View(await _context.Intermediaries.ToListAsync());
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("ID")] Intermediaries Intermediaries)
{
 if (ModelState.IsValid)
 {
 _context.Add(Intermediaries);
 await _context.SaveChangesAsync();
 return RedirectToAction(nameof(Index));
 }
 return View(Intermediaries);
}

The same goes for my views

My View

@model IEnumerable<BizDevHub.Models.Intermediary>
@{
 ViewData["Title"] = "Index";
 Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Index</h2>
<p>
 <a asp-action="Create">Create New</a>
</p>
<table class="table">
 <thead>
 <tr>
 <th>
 @Html.DisplayNameFor(model => model.RegisteredName)
 </th>
 <th>
 @Html.DisplayNameFor(model => model.TradingName)
 </th>
 <th>
 @Html.DisplayNameFor(model => model.Registration)
 </th>
 <th>
 @Html.DisplayNameFor(model => model.VATNumber)
 </th>
 <th>
 @Html.DisplayNameFor(model => model.FSPNumber)
 </th>
 <th>
 @Html.DisplayNameFor(model => model.CreatedDate)
 </th>
 <th>
 @Html.DisplayNameFor(model => model.CreatedBy)
 </th>
 <th></th>
 </tr>
 </thead>
 <tbody>
@foreach (var item in Model) {
 <tr>
 <td>
 @Html.DisplayFor(modelItem => item.RegisteredName)
 </td>
 <td>
 @Html.DisplayFor(modelItem => item.TradingName)
 </td>
 <td>
 @Html.DisplayFor(modelItem => item.Registration)
 </td>
 <td>
 @Html.DisplayFor(modelItem => item.VATNumber)
 </td>
 <td>
 @Html.DisplayFor(modelItem => item.FSPNumber)
 </td>
 <td>
 @Html.DisplayFor(modelItem => item.CreatedDate)
 </td>
 <td>
 @Html.DisplayFor(modelItem => item.CreatedBy)
 </td>
 <td>
 <a asp-action="Edit" asp-route-id="@item.IntermediaryID">Edit</a> |
 <a asp-action="Details" asp-route-id="@item.IntermediaryID">Details</a> |
 <a asp-action="Delete" asp-route-id="@item.IntermediaryID">Delete</a>
 </td>
 </tr>
}
 </tbody>
</table>

What am I doing wrong?

Thanks in advance.

asked Jan 12, 2020 at 12:52

1 Answer 1

2

@Anonymous is correct that you need to redesign the View model. There is no point having a view model if you are just assigning entities as the properties, the purpose of the view model is to separate you controller and view from your datacontext

public class IntermediariesViewModel
{
 public int Id { get; set; }
 public string RegisteredName { get; set; }
 public string TradingName { get; set; }
 //other properties
 IEnumerable<BranchViewModel> Branches { get; set; }
}
public class BranchViewModel
{
 public int Id { get; set; }
 public string Name { get; set; }
}

View:

@model IEnumerable<BizDevHub.Models.IntermediariesViewModel>

EDIT : but how would you combine both view models in a single controller and view with methods like Index, Edit and Delete?

Controller:

public IActionResult Update([FromBody]IntermediariesViewModel model)
 {
 var intermediary = _context.Intermediaries.Where(x=> x.IntermediaryID == model.Id).FirstOrDefault();
 if(intermediary != null)
 {
 intermediary.RegisteredName = model.RegisteredName ;
 //rest of updates
 _context.SaveChanges();
 }
 }
 public IActionResult Delete([FromBody]int IntermediariesId)
 {
 var intermediary = _context.Intermediaries.Where(x=> x.IntermediaryID == IntermediariesId).FirstOrDefault();
 if(intermediary != null)
 {
 _context.Intermediaries.Remove(intermediary); 
 _context.SaveChanges();
 }
 }

View:

@Html.DisplayNameFor(model => model.RegisteredName)
@Html.DisplayNameFor(model => model.BranchViewModel[0].Name)// first branch name, you may want to iterate
answered Jan 13, 2020 at 12:28

2 Comments

Thank you Vince, but how would you combine both view models in a single controller and view with methods like Index, Edit and Delete?
@JasonEbersey see update, also hello fellow South African

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.