I am currently working on my first ASP.NET Core MVC project with a repository pattern.
I have gotten it to work but I wonder if there is a better way to solve this.
In this case I have an Organization model and an Address model, with OrganizationData and AddressData for the repositories.
What I am wondering about the most is how I handled the relationship between organization and address.
Organization model
using System;
using System.ComponentModel.DataAnnotations;
namespace Verbonding.Models
{
public class Organization
{
public int Id { get; set; }
[Required, MaxLength(80)]
[DataType(DataType.Text)]
[Display(Name = "Organization Name")]
public string Name { get; set; }
[DataType(DataType.EmailAddress)]
public string Email { get; set; }
[DataType(DataType.Url)]
public string Website { get; set; }
public int AddressId { get; set; }
public bool IsActive { get; set; }
public bool IsBlocked { get; set; }
public DateTime DateCreated { get; set; }
public DateTime DateUpdated { get; set; }
public virtual Address Address { get; set; }
public Organization()
{
IsActive = true;
IsBlocked = false;
DateCreated = DateTime.Now;
DateUpdated = DateTime.Now;
}
}
}
Address model
using System.ComponentModel.DataAnnotations;
namespace Verbonding.Models
{
public class Address : IAddress
{
public int Id { get; set; }
[Required]
public string Street { get; set; }
[Required]
public string HouseNr { get; set; }
[Required]
public string PostalCode { get; set; }
[Required]
public string City { get; set; }
public int? CountryId { get; set; }
public virtual Country Country { get; set; }
}
}
OrganizationData repository
What I am wondering about here is if the GetAll() method could me a bit nicer.
using System.Collections.Generic;
using System.Linq;
using Verbonding.Data;
using Verbonding.Models;
namespace Verbonding.Services
{
public class OrganizationData : IOrganizationData
{
private ApplicationDbContext _context;
public OrganizationData(ApplicationDbContext context)
{
_context = context;
}
public Organization Add(Organization organization)
{
_context.Add(organization);
return organization;
}
public void Commit()
{
_context.SaveChanges();
}
public void Delete(int id)
{
Organization organization = Get(id);
_context.Remove(organization);
}
public Organization Get(int id)
{
return _context.Organizations.FirstOrDefault(o => o.Id == id);
}
public IEnumerable<Organization> GetAll()
{
IEnumerable<Organization> organizations = _context.Organizations;
var addressData = new AddressData(_context);
foreach (Organization o in organizations)
{
o.Address = addressData.Get(o.AddressId);
}
return organizations;
}
}
}
AddressData repository
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Verbonding.Data;
using Verbonding.Models;
namespace Verbonding.Services
{
public class AddressData : IAddressData
{
private ApplicationDbContext _context;
public AddressData(ApplicationDbContext context)
{
_context = context;
}
public Address Add(Address address)
{
_context.Add(address);
return address;
}
public void Commit()
{
_context.SaveChanges();
}
public void Delete(int id)
{
Address address = Get(id);
_context.Addresses.Remove(address);
}
public Address Get(int id)
{
return _context.Addresses.FirstOrDefault(a => a.Id == id);
}
public IEnumerable<Address> GetAll()
{
return _context.Addresses;
}
}
}
OrganizationViewModel
namespace Verbonding.Models.OrganizationViewModels
{
public class OrganizationViewModel
{
public string Name { get; set; }
public string Email { get; set; }
public string Website { get; set; }
public string Street { get; set; }
public string HouseNr { get; set; }
public string PostalCode { get; set; }
public string City { get; set; }
public Country Country { get; set; }
}
}
IndexViewModel
using System.Collections.Generic;
namespace Verbonding.Models.OrganizationViewModels
{
public class IndexViewModel
{
public IEnumerable<Organization> Organizations{ get; set; }
}
}
OrganizationsController
I have left some methods out here that have not been implemented yet.
In the POST Create() method I am mapping the values manually to the model, and saving them to the repository.
Is there a better way to do this, or is this fine the way it is.
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Verbonding.Models;
using Verbonding.Services;
using Verbonding.Models.OrganizationViewModels;
namespace Verbonding.Controllers
{
public class OrganizationsController : Controller
{
private IOrganizationData _organizationData;
private IAddressData _addressData;
public OrganizationsController(IOrganizationData organizationData,
IAddressData addressData)
{
_organizationData = organizationData;
_addressData = addressData;
}
// GET: Organizations
public IActionResult Index()
{
var model = new IndexViewModel();
model.Organizations = _organizationData.GetAll();
return View(model);
}
// GET: Organizations/Create
public IActionResult Create()
{
return View();
}
// POST: Organizations/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 IActionResult Create(OrganizationViewModel organization)
{
if (ModelState.IsValid)
{
var newOrganization = new Organization();
var newAddress = new Address();
newOrganization.Name = organization.Name;
newOrganization.Email = organization.Email;
newOrganization.Website = organization.Website;
_organizationData.Add(newOrganization);
newAddress.Street = organization.Street;
newAddress.HouseNr = organization.HouseNr;
newAddress.PostalCode = organization.PostalCode;
newAddress.City = organization.City;
newAddress.Country = organization.Country;
_addressData.Add(newAddress);
newOrganization.Address = newAddress;
_organizationData.Commit();
return RedirectToAction("Index");
}
return View(organization);
}
}
}
Thanks