Keri sisuni

Mudelite klassid

ASP.NET Core ja teistes MVC rakendustes kasutatakse mudeliteks nimetatavaid klasse selleks, et vahendada andmeid kasutusliidese ja kontrollerite vahel. Mudelite klassid asuvad Models kataloogis, mis meil on hetkel peaaegu tühi. Samas tagastavad meie teenused meile objekte, mis on defineeritud Data kataloogis.

Joonis juurde

// Meetod InvoiceService klassis
public async Task<IList<Invoice>> List()
{
    return await _dataContext.Invoices.Include(invoice => invoice.Customer)
                                      .OrderByDescending(invoice => invoice.Date)
                                      .ToListAsync();
}

On aeg teha järgmine samm arhitektuuri ja tehnilise disaini maailmas ning luua endale selgus, et mis klassid on mis ja kuidas neid kasutama peaks. Me hakkame nüüd tasapisi eemalduma lihtsate algajate näidete maailmast ning sisenema päris elu poolele.

Klassid Data kataloogis

Data kataloogis olevad klassid on digitaalsed elementaarosakesed, mis kannavad meie süsteemi loogikat. Neid klasse nimetatakse ka äriloogikaklassideks ja domeeniklassideks. Nende struktuur ja sisu vastab sellele, mis me oleme süsteemi modelleerimisel paika pannnud. Kuigi seni oleme me nende klassidega hakkama saanud kasutusliidese teenindamisel, ei saa me selliselt kuigi pikalt jätkata, sest kasutusliidese teenindamiseks mõeldud mudeliklasside ja kasutajatele nähtamatute domeeniklasside struktuur ei ole 1:1 vastavuses.

Selgituseks vaatleme vormi, kus saab lisada uue auto.

Pilt

Näeme, et sellel vormil on võimalik valida ripploendist kasutaja, kes antud autot haldab. Samuti saame ripploendist valida auto mudeli. Selliseid omadusi, mis annaks meile loendi kasutajatest ja auto mudelitest, meil Data kataloogis olevas Car klassis ei ole. Car klassile nende omaduste lisamine ei omaks mingit mõtet ja mis veel hullem - nende omaduste lisamisel kajastuks see ka andmebaasi struktuuris kui me andmebaasi genereerida laseme oma rakendusel.

Klassid Models kataloogis

Models kataloogis on klassid, mis on mõeldud vaadete teenindamiseks ning andmete liigutamiseks brauseri ja meie rakenduse vahel. Need mudelid on mõneti sarnased Data kataloogis olevatele klassidele, kuid nad pole sama ülesehitusega. Vaatame mudeliklassi CarEditModel, mida kasutame autode lisamise ja muutmise vormil. Võrdluseks võtame kõrvale Car klassi, mis on Data kataloogis ja mille andmeid hoitakse andmebaasis.

CarEditModel Car
public class CarEditModel
{
    public int Id { get; set; }
    public string RegistrationNo { get; set; }

    public int ManagerId { get; set; }
    public int CarModelId { get; set; }

    public IList<SelectListItem> Managers { get; set; }
    public IList<SelectListItem> CarModels { get; set; }

    public CarEditModel()
    {
        Managers = new List<User>();
        CarModels = new List<CarModel>();
    }
}
public class CarEditModel
{
    public int Id { get; set; }
    public string RegistrationNo { get; set; }

    public User Manager { get; set; }
    public CarModel Model { get; set; }
}

Näeme, et CarEditModel klassil on halduri ja auto mudeli jaoks ID omadused - ManagerId ja CarModelId. Car klassil on selle asemel omadused Manager ja CarModel. CarEditModel klassil on omadused Managers ja CarModels, et tuua muutmisvaatesse haldurite ja auto mudelite loendid. Car klassil neid omadusi pole, sest neil puuduks süsteemi andmemudeli seisukohalt igasugune tähendus.

Kui palju mudeleid meil on vaja?

Mudelite arv sõltub suuresti kasutusliidesest ja sellest palju meil on vaateid. Osasid mudeleid saame kasutada mitme vaatega, kuid võib olla ka vaateid, mille jaoks kasutame mitut mudeliklassi.

Mudeli klassid ja vaated, millega need on seotud

Teisendamine Data ja Models kaustade klasside vahel

Kui me läheme vaadetes üle mudeliklassidele, siis peame me liigutama andmeid Data ja Models kaustade klasside vahel. Auto andmete muutmiseks peame me vaatesse kaasa andma Car asemel CarEditModel klassi.

Enne Nüüd
public class CarsController : Controller
{
    // ...

    public async Task<Car> Edit(int? id)
    {
        if(id == null)
        {
            return NotFound();
        }

        // tagastab Car-tüüpi objekti (Data kaust)
        var car = await _carService.GetById(id.Value);
        if(car == null)
        {
            return NotFound();
        }

        // Anname kaasa andmed rippnimistute täitmiseks
        ViewBag.Managers = await _userService.ListAll();
        ViewBag.CarModels = await _carService.ListModels();

        return View(car);
    }
}
public class CarsController : Controller
{
    // ...

    public async Task<Car> Edit(int? id)
    {
        if(id == null)
        {
            return NotFound();
        }

        // tagastab CarEditModel-tüüpi objekti (Models kaust)
        var model = await _carService.GetById(id.Value);
        if(model == null)
        {
            return NotFound();
        }

        // Anname kaasa andmed rippnimistute täitmiseks
        model.Managers = (await _userService.ListAll())
                                           .Select(u => new SelectListItem 
                                           {
                                               Text = u.UserName,
                                               Value = u.Id.ToString(),
                                               Select = (u.Id == model.ManagerId)
                                           });
        model.CarModels = (await _carService.ListModels())
                                           .Select(cm => new SelectListItem 
                                           {
                                               Text = cm.Name,
                                               Value = cm.Id.ToString(),
                                               Select = (md.Id == model.CarModelId)
                                           });

        return View(MOdel);
    }
}