Devo avere modelli separati per EF e front end (fino al livello del controller)?

2

I modelli per il database (utilizzando EF6) hanno determinati attributi come Key , NotMapped o Required (che imposterà la colonna in SQL Server a not null ) mentre i modelli che interagiscono con la parte MVC di il sito web ha i propri attributi. Un esempio di questo è anche Required che uso per la convalida dei dati quando un utente sta inviando un modulo e che farà cose di fantasia come i messaggi di errore di visualizzazione sulla pagina web (quando controllo Model.IsValid ).

La mia domanda è se questi due "gruppi" di attributi del metodo sono compatibili o dovrei avere un set di modelli che uso per l'interazione con EF e un altro insieme di modelli che vengono utilizzati per spostare i dati tra i livelli Logic / DataAccess e il controller. L'idea sarebbe quella di utilizzare qualcosa come AutoMapper tra i due set di modelli.

Se necessario, ovviamente creerò ViewModels e mapperò tutto ciò di cui ho bisogno.

    
posta birdus 28.04.2017 - 19:04
fonte

1 risposta

5

I vincoli degli attributi sono l'ultimo dei tuoi problemi. I modelli EF non sono oggetti POCO , sono entità DTO strettamente interconnesse allo schema del tuo database e DbContext / DbSet s.

C'è un'enorme quantità di logica invisibile in agguato dietro quelle proprietà di get e set dall'aspetto innocente; loro (le entità DTO) fanno tutti i tipi di cose magiche "EF", come ad esempio:

  • Traduci le tue query da LINQ a entità in SQL
  • Gestisci il caricamento lento
  • I modelli EF sono anche legati in EntityState per DbContext

Sfortunatamente, molte esercitazioni ASP.NET su MVC sono state introdotte nei controller. Quei tutorial ti insegnano una cattiva abitudine che ti morderà non appena proverai a fare qualcosa di non banale

Ad esempio, immagina di avere un modello EF Employee , che ha anche un metodo in esso chiamato GetManager() .

Vedi questo bit di LINQ, sembra innocente vero?

var managers = from emp in MyDbContext.Employees
               where emp.Department == "Sales"
               select emp.GetManager();

se MyDbContext.Employees fosse qualcosa di semplice come un List<Employee> dove Employee è un POCO regolare, questo andrebbe bene. ma sfortunatamente la suddetta query genererà un'eccezione perché tenta di convertire emp.GetManager() in un'istruzione SQL - eccetto che non esiste qualcosa come GetManager in SQL ...

Un altro problema: se possiedi proprietà lazy-loaded che tenti di utilizzare dopo DbContext.Dispose() , ti troverai a dover caricare forzatamente la proprietà prima di eliminarla (e ricorda di impostare anche EntityState.Detached ), o eseguendo tutta la tua logica aziendale all'interno del tuo blocco using .

Naturalmente, potrebbe essere ok se hai una logica di business molto semplice a cui interessano solo alcune semplici entità di database; è necessario mantenere la prospettiva e ricordare che KISS è anche importante.

Tuttavia, è ragionevole aspettarsi che tu possa anche prendere alcuni dati da un'altra fonte, come un file, un servizio di rete, un'altra API o altro database, ecc. La logica aziendale che si verifica all'interno di un blocco EF using è un percorso comune al debito tecnico e al codice difficile da mantenere.

Naturalmente, tutte queste sono cose che puoi "aggirare", ma è probabile che il risultato significhi combinare tutta la tua logica dell'interfaccia utente con la tua logica aziendale e di livello dati; la separazione delle preoccupazioni dell'interfaccia utente rispetto alle problematiche del database diventa scomoda quando si utilizzano modelli EF in Controller .

Quindi, stai molto attento quando decidi di utilizzare i modelli EF direttamente nei tuoi controller MVC perché qualsiasi cosa marginalmente non banale può vederti combattere tutti i tipi di eccezioni lanciate da EF che non vedresti in modelli POCO mappati regolarmente. Il prezzo da pagare per la quantità nominale di codice boilerplate che mappa dai tuoi modelli EF ai tuoi modelli di 'Business Layer' è molto ragionevole, rispetto al terribile debito tecnico con cui potresti finire in altro modo.

    
risposta data 28.04.2017 - 19:25
fonte

Leggi altre domande sui tag