825 messaggi dal 11 febbraio 2013
Volevo chiedere se cè qualche controindicazione nel creare molte relazioni tra classi

Per esempio ho bisogno di leggere giacenze e ordini a fornitori relativi agli articoli
cosi vorrei legare queste due entità alla classe articolo.

Queste due entità le userei poco percui pensavo che se è 'sbagliato' aggiungere troppe relazioni
potrei fare dei join

grazie per i suggerimenti
11.448 messaggi dal 09 febbraio 2002
Contributi
Ciao,
penso che due navigation property in più non causino problemi di performance. Dovresti sempre preferirle alle join.


giacenze e ordini a fornitori

Se la tua applicazione dovesse crescere e cominci ad avere la sensazione di avere "troppe" classi che usi poco, potresti cominciare a separare i due contesti. Le giacenze fanno parte del contesto della gestione di magazzino, mentre gli ordini ai fornitori del contesto di riassortimento.
Perciò potresti modellare questi due contesti con due DbContext diversi, in modo da avere poche classi dall'una e dall'altra parte. Sicuramente capiterà che avranno dei punti di contatto e quindi ti potrai avere la tentazione mappare una stessa classe in entrambi i contesti (ad esempio quella che rappresenta una riga di carico). In realtà anche questa classe "comune" potresti scinderla in due classi diverse, perché è difficile che nei due DbContext tu abbia la necessità di leggere e scrivere TUTTE le sue proprietà. Ad esempio, lato riassortimento avrà una relazione con la classe di entità che contiene l'anagrafica completa del fornitore, mentre lato gestione di magazzino magari mapperai solo la chiave del fornitore (sto facendo esempi grossolani senza conoscere il tuo scenario, eh).

Prendi una ventina di minuti per leggere attentamente questo articolo di Julie Lerman che parla appunto dei "bounded context".
https://msdn.microsoft.com/en-us/magazine/jj883952.aspx

ciao,
Moreno
Modificato da BrightSoul il 21 marzo 2019 19:50 -

Enjoy learning and just keep making
825 messaggi dal 11 febbraio 2013
Ok

ma ho una domanda

se dovessi trovarmi in difficoltà a relazionare le tabelle dovendo eseguire una query
con 4 tabelle sarebbe sbagliato fare cosi per ritornare un json?

_ctx.Database.ExecuteSqlCommandAsync("SELECT...");

influirebbe sulle performance?
11.448 messaggi dal 09 febbraio 2002
Contributi

influirebbe sulle performance?

No, le performance migliorerebbero un pelo perché stai inviando una query diretta al database e così facendo bypassi di fatto lo strato di mapping di Entity Framework.

Però devi chiederti questo: hai scelto di usare EF e poi invii query SQL, perché?
  • Se non riesci a creare le relazioni tra le classi di entità a causa di lacune sull'utilizzo di EF, allora la soluzione non è inviare una query SQL ma colmare le lacune e poi usare le proprietà di navigazione;
  • Se la query fa uso di funzionalità avanzate di SQL Server che non puoi replicare con una query LINQ, allora va bene inviare una query SQL


ciao,
Moreno

Enjoy learning and just keep making
825 messaggi dal 11 febbraio 2013
Si lacune

ma non so come fare

Ho le classi cosi
 class Articolo{
 public string Codart { get; set; }//key
  ...
 public List<Variante> Varianti { get; set; }

}

class Variante{
 public string Codart { get; set; }//key
 public string Variante { get; set; }//key
}

class Esistenze
{
 public string Codart { get; set; }//key
 public string Variante { get; set; }//key
 public int Esistenza { get; set; }
}

class Impegnato
{
 public string Codart { get; set; }//key
 public string Variante { get; set; }//key
 public int ImpegnatoCliente  { get; set; }
 public int ImpegnatoFornitore  { get; set; }
}



Debbo solo ritornare un json dove avere la disponibilità=> Esistenza-ImpegantoCliente + ImpegnatoFornitore

Si ho difficoltà ad includere Esistenze e Impegnato in Articolo :(
11.448 messaggi dal 09 febbraio 2002
Contributi
Prova a seguire questo esempio, ti mostra come modellare una relazione uno a molti come la tua, che usa una foreign key composta di sue campi.

Vedi il secondo esempio del capitoletto "Chiave esterna".
https://docs.microsoft.com/it-it/ef/core/modeling/relationships#foreign-key

ciao,
Moreno

Enjoy learning and just keep making
825 messaggi dal 11 febbraio 2013
Ciao Moreno,
ho fatto cosi

//sqlite
CREATE TABLE Esistenze( 
[Codart] TEXT NOT NULL, 
[Codvar] TEXT NOT NULL, 
[Esiste] REAL NOT NULL, 
CONSTRAINT [PK_Esistenze] PRIMARY KEY ( [Codart], [Codvar] ), 
CONSTRAINT FK_Articoli FOREIGN KEY (Codart) REFERENCES Articoli(Codart) ON DELETE CASCADE, 
CONSTRAINT FK_Varianti FOREIGN KEY (Codvar) REFERENCES Varianti(Codvar) ON DELETE CASCADE 
)


class Articolo{
        public string Codart { get; set; }
        public string Descri { get; set; }
        ...

        public List<Variante> Varianti { get; set; }
        public Esistenza Esistenza { get; set; }
}


public void Configure(EntityTypeBuilder<Esistenza> builder)
        {
            builder.HasKey(e => new {e.Codart, e.Codvar});
            builder.Property(e => e.Esiste).IsRequired();

             builder
           .HasOne(a => a.Articolo)
           .WithOne(e => e.Esistenza)
           .HasForeignKey<Esistenza>(f => new {f.RkaCodart,f.RkaCodvar});
 }

public class Esistenza
    {
        public string Codart { get; set; }
        public string Codvar { get; set; }
        public double Esiste { get; set; }
        
        public Articolo Articolo { get; set; }
     
    }


ottengo questo errore

The relationship from 'Esistenza.Articolo' to 'Articolo.Esistenze' with foreign key properties {'Codart' : string, 'Codvar' : string} cannot target the primary key {'Codart' : string} because it is not compatible

Questo perchè la classe articolo ha chiave Codart

Ma come faccio a dirgli che deve puntare a Articolo.Variante.Codvar ?

sbaglio?
Modificato da jjchuck il 24 marzo 2019 18:55 -
11.448 messaggi dal 09 febbraio 2002
Contributi
Ciao,
stai mappando una relazione uno a uno tra Articolo (entità principale) e Esistenza (entità dipendente). Il codice che hai usato per costruire la tabella Esistenze è questo:
CREATE TABLE Esistenze( 
[Codart] TEXT NOT NULL, 
[Codvar] TEXT NOT NULL, 
[Esiste] REAL NOT NULL, 
CONSTRAINT [PK_Esistenze] PRIMARY KEY ( [Codart], [Codvar] ), 
CONSTRAINT FK_Articoli FOREIGN KEY (Codart) REFERENCES Articoli(Codart) ON DELETE CASCADE, 
CONSTRAINT FK_Varianti FOREIGN KEY (Codvar) REFERENCES Varianti(Codvar) ON DELETE CASCADE 
)

...e credo che sia corretto, perché hai creato una foreign key che coinvolge solo il campo Codart, che di fatti è anche la chiave primaria sulla tabella Articoli.

Quindi devi esprimere la stessa cosa anche da interfaccia fluente.
  builder
           .HasOne(a => a.Articolo)
           .WithOne(e => e.Esistenza)
           .HasForeignKey(e => e.Codart);


Attenzione perché potrebbe non funzionare lo stesso. Infatti, da una relazione uno-a-uno, mi aspetto che per ogni articolo possa esistere solo un'esistenza. Ma così in realtà non è, perché tu nella tabella esistenze, per come l'hai costruita, puoi avere molteplici record con lo stesso CodArt. Infatti hai impostato una chiave primaria composita che ammette questo:
CodArt, CodVar
1, 1
1, 2
1, 3
1, 4

Vedi quanti uno duplicati per CodArt? Questa è in realtà una relazione uno-a-molti che esiste tra Articolo ed Esistenza.
Per come l'hai strutturato, mi sembra che Esistenza debba essere relazionato a Variante, e non ad Articolo.
La chiave primaria di Variante qual è?

ciao,
Moreno
Modificato da BrightSoul il 25 marzo 2019 08:30 -

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.