23 messaggi dal 03 aprile 2014
Salve ragazzi, dopo anni di php e laravel per motivi lavorativi sto passando a .net core.

ho iniziato a leggere qualcosa dal sito microsoft.

ma adesso ho un piccolo problema che non riesco a risolvere.

provenendo da laravel, per la gestione del model, bastava crearlo da pannello di comandi e me lo ritrovavo sul controller per interrogarlo.

Vorrei fare la stessa cosa con EFcore ma non capisco come fare, sul sito ufficiale si parla di Models ma subito dopo mi costringe a fare lo Scaffolding, cosa che a me non interessa minimamente.

in breve creato il Model Magazzino, Come faccio a richiamarlo da HomeController?

Thanks
10.957 messaggi dal 09 febbraio 2002
Contributi
Ciao,

in breve creato il Model Magazzino,


Ok, quindi hai la tua classe Magazzino e l'hai mappata nel tuo DbContext più o meno così:
public class MyContext : DbContext
{

    public MyContext(DbContextOptions<MyContext> options)
        : base(options)
    {
    }

    public virtual DbSet<Magazzino> Magazzini { get; set; }


    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Magazzino>().ToTable("Magazzini");
    }
}


Ora devi registrare il DbContext nel metodo ConfigureServices della classe Startup.
services.AddDbContext<MyContext>();


A questo punto lo puoi ricevere nel costruttore dell'HomeController grazie al meccanismo di dependency injection di ASP.NET Core.
public class HomeController : Controller {
  private readonly MyContext context;
  public HomeController(MyContext context) {
    this.context = context;
  }

  public async Task<IActionResult> Index() {
     //Qui usa LINQ per interrogare Magazzini
     var magazziniDiRoma = await context.Magazzini.Where(magazzino => magazzino.Citta == "Roma").ToListAsync();

     //Qui fai qualcosa con gli oggetti che hai ottenuto...
     //E poi restituisci la View
     return View();
  }
}


In alternativa al costruttore, lo puoi ricevere come parametro dell'action, purché usi l'attributo [FromServices]
public class HomeController : Controller {

  public async Task<IActionResult> Index([FromServices] MyContext context) {
     //Qui usa LINQ per interrogare Magazzini
     var magazziniDiRoma = await context.Magazzini.Where(magazzino => magazzino.Citta == "Roma").ToListAsync();

     //Qui fai qualcosa con gli oggetti che hai ottenuto...
     //E poi restituisci la View
     return View();
  }
}



bastava crearlo da pannello di comandi e me lo ritrovavo sul controller per interrogarlo.

Beh, questo è considerabile "scaffolding"... come mai dici che non ti interessa fare la stessa cosa con Entity Framework Core?

ciao,
Moreno
Modificato da BrightSoul il 03 ottobre 2018 19.36 -

Enjoy learning and just keep making
23 messaggi dal 03 aprile 2014
intanto grazie per la tua risposta.

perchè fino ad oggi intendevo lo scaffolding dove visualstudio mi creava le view per l'edit, create etc..

ora ho scoperto lo scaffolding per la creazione dei model e dei context per ogni tabella.
però continuo a non capirci niente.

quindi se devo usare due tabelle all'interno di un controller

 private readonly MyContext context;
  public HomeController(MyContext context) {
    this.context = context;
  } 

private readonly MyContext2 context2;
  public HomeController(MyContext2 context2) {
    this.context2 = context2;
  }


tutto sto casino per ogni model????

Comunque non sò come ho fatto ma ho caricato tutto su cartella data, dentro ho inserito un nomeprogettoContext.cs ed all'interno ho scritto

 public DbSet<xxx.Models.PlanimetriaMagazzini> PlanimetriaMagazzini { get; set; }
        public DbSet<xxxx.Models.Magazzini> Magazzini { get; set; }


E quindi nel Controller mi richiamo il file context e posso utilizzare le tabelle senza scrivere quanto fatto soprà, però se ho più key in un model, non posso scrivere [key]chiave1 [key]chiave2 ma devo usare le API fluent....mha!!!!!

poi quando cerco su google join con EFcore, alcuni mi fanno usare .Join invece sul sito ufficiale mi fà usare include e theninclude....e in tutto questo continuo a non capirci niente.

poi tu mi parli di LINQ, ma perdonami ma EFCORE non dovrebbe sostituire LINQ??
10.957 messaggi dal 09 febbraio 2002
Contributi
Ciao, prego.


però continuo a non capirci niente.

Questo è normale e succede perché stai affrontando troppi argomenti contemporaneamente. Devi organizzare il tuo studio procedendo poco alla volta, in maniera strutturata e prendendoti del tempo per digerire bene ogni cosa. Meglio ancora sarebbe se ti procurassi un libro o se ti affiancassi a una persona già esperta in ASP.NET Core.

L'acqua della piscina è piacevole se ci entri gradualmente. Se invece ti tuffi a bomba da un trampolino di 10 metri avrà la consistenza del granito.
Detto questo, cercherò di aiutarti come posso a sbrogliare la matassa.


quindi se devo usare due tabelle all'interno di un controller
tutto sto casino per ogni model????

Ovviamente no perché ogni DbContext può accogliere più di un DbSet (quanti ne vuoi), che sono il tuo punto di ingresso per interrogare il modello concettuale.

public DbSet<xxx.Models.PlanimetriaMagazzini> PlanimetriaMagazzini { get; set; }
public DbSet<xxxx.Models.Magazzini> Magazzini { get; set; }

Questo è corretto, hai creato 2 DbSet nello stesso DbContext e questo ti permetterà di interrogare sia l'entity set PlanimetriaMagazzini che Magazzini. Ti consiglio questo:

Rinomina le classi di entità al singolare, perché ciascuna di esse rappresenta un singolo oggetto. Quindi Magazzini rinominala in Magazzino, mentre PlanimetriaMagazzini rinominala PlanimetriaMagazzino. Puoi rinominare facilmente facendo tasto destro sul nome -> Rinomina (o tasto F2). In alternativa puoi anche andare a rinominare direttamente il file Magazzini.cs: Visual Studio ti chiederà se vuoi cambiare anche il nome della classe. Tu accetta.

I nomi delle proprietà di tipo DbSet invece vanno bene così perché rappresentano degli insiemi. Quindi il codice rivisto sarà così:
public DbSet<PlanimetriaMagazzino> PlanimetriaMagazzini { get; set; }
public DbSet<Magazzino> Magazzini { get; set; }

Come vedi ho tolto anche xxx.Models perché non vale la pena ripeterlo ogni volta dato che puoi aggiungere uno using xxx.Models; in cima al file .cs.


E quindi nel Controller mi richiamo il file context e posso utilizzare le tabelle senza scrivere quanto fatto soprà,

MyContext e MyContext2 eliminali, dato che ormai stai lavorando con nomeprogettoContext.


però se ho più key in un model, non posso scrivere [key]chiave1 [key]chiave2 ma devo usare le API fluent....mha!!!!!

EFCore è un prodotto ancora giovane e non ha ancora questa funzionalità. C'è una issue aperta su GitHub a riguardo, sintomo che il problema è noto e che prossimamente verrà lavorato dal team di sviluppo.

A prescindere da questo, io ti consiglio di usare sempre la fluent API per due motivi:
  • Come hai avuto modo di notare, offre più funzionalità rispetto agli attibuti;
  • Ti permette di centralizzare la logica di mapping, che altrimenti sarebbe sparsa in giro per il progetto (ma è questione di gusti);
  • Ti permette di mantenere le tue classi di entità realmente agnostiche sul come verranno persistite e questo, come leggi qui, è una cosa che ha senso fare anche in PHP.



poi quando cerco su google join con EFcore, alcuni mi fanno usare .Join invece sul sito ufficiale mi fà usare include e theninclude....e in tutto questo continuo a non capirci niente.

Join non si usa perché con EFCore, così come con gli ORM del PHP, si possono mappare relazioni tra entità ed accedervi tramite proprietà di navigazione. Leggi qui:
https://www.learnentityframeworkcore.com/configuration/one-to-many-relationship-configuration
Per "proprietà di navigazione" si intende una proprietà che ti permette da un lato all'altro della relazione. Nella pagina qui sopra vedi appunto l'esempio di una relazione tra Company e Employee (una Company ha molti Employee).
Se hai tra le manu un oggetto di tipo Company e vuoi conoscere quali Employee lavorano per essa, ti basterà scrivere, così, senza usare alcuna Join.
var employees = company.Employees;


Nel momento in cui accedi alla proprietà Employees, EFCore interviene dietro le quinte e invia una query SQL al database per recuperare gli Employee. Questo può essere un problema, specialmente se nel database hai 1000 Company e le cicli con un foreach per estrarre gli Employee da ciascuna di esse. Se hai abilitato il lazy loading e senza che tu ne sia realmente consapevole, EFCore sta inviando 1000 query distinte al database, una per ogni lista di Employee che stai ciclando, facendoti pagare 1000 volte il seppur piccolo overhead che deriva dall'inviare una query al database. Questo è noto come problema "Select N+1" e riguarda tutti gli ORM in tutti i linguaggi.

Quindi, se già sai a propri che andrai e leggere quegli Employee, puoi manifestare questa tua intenzione a EFCore con il metodo Include, in modo da recuperare tutti i dati delle entità relazionate con una sola query, che è decisamente più efficiente di inviarne 1000. Questo è noto come "eager loading" che penso tu conosca dato che avrai sicuramente usato Doctrine e/o Eloquent.


poi tu mi parli di LINQ, ma perdonami ma EFCORE non dovrebbe sostituire LINQ??

LINQ è l'insieme degli extension method che ti permettono di interrogare il modello concettuale. Quando usi i metodi Where, OrderBy, Select, ecc.. stai usando LINQ. In questo caso LINQ sta agendo sugli insiemi esposti dal DbContext per mezzo dei DbSet ma LINQ è una funzionalità del linguaggio C# che puoi usare per interrogare collezioni di oggetti in memoria, su file XML, su DataSet e da una serie di altre fonti.

Quindi, LINQ è uno strumento di interrogazione, non è una tecnologia di accesso ai dati.
Quello che forse intendi tu è "Linq To Sql" che è un progenitore di Entity Framework e che nessuno usa più da 10 anni.

Se hai altre domande scrivi qui, non lasciare che la frustrazione influenzi la tua opinione su ASP.NET Core.
ciao,
Moreno

Enjoy learning and just keep making

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.