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.
1 Answer 1
@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
2 Comments
Explore related questions
See similar questions with these tags.