9 messaggi dal 09 novembre 2016
Ciao a tutti!

Ho questo quesito.
Partendo da una classe base ho la necessità di estenderla con alcuni campi aggiuntivi che vado a valorizzare tramite join in questo modo:

[Classe base]
public partial class Log
{
        public int LogID { get; set; }
        public int ActionID { get; set; }
        public DateTime InsertDate { get; set; }
}


che vado ad estendere così per avere valorizzato il nome dell'azione del log che si trova in una tabella collegata:

[Estensione della classe]
public partial class LogInfo : Log
{
        public string ActionName { get; set; }
}


Per ora ho sempre utilizzato due strade:

1) Tramite native SQL e cioè:
var qry = "select a.*, b.ActionName From Logs a join LogActions b on etc.."
var list = db.Database.SqlQuery<LogInfo>(qry).ToList();


2) Tramite Linq ma dovendo prima modificare la classe estesa in questo modo:
public partial class LogInfo
{
        public Log Log { get; set; }
        public string ActionName { get; set; }
}

per poi fare la query in questo modo:
var list = from a in db.Logs
                         join b in db.LogActions on a.ActionID equals b.ActionID
                         select new LogInfo()
                         {
                             Log = a,
                             ActionName = b.Name
                         };

La domanda quindi è:
esiste in modo più snello di popolare una classe estesa e/o c'è un modo per farlo, sempre con Linq, evitando di inserire una proprietà nell'oggetto da estendere?

Grazie in anticipo
11.886 messaggi dal 09 febbraio 2002
Contributi
Ciao,
Entity Framework supporta l'ereditarietà e, nel tuo caso, ti consiglio di usare il modello Table-per-type.
Prova a seguire questo articolo:
https://www.codeproject.com/Articles/796521/Inheritance-in-Entity-Framework-Table-Per-Type

Come nel tuo caso, c'è una classe Friend (equivalente alla tua LogInfo) che deriva da una classe base Person (la tua Log). I dati comuni alle due classi vengono memorizzati in una tabella People, mentre la proprietà aggiuntiva IsClassMate (la tua ActionName) nella tabella Friend.

Entity Framework si occupa di fare la join, quindi non dovrai più preoccuparti di farlo tu.

Per ottenere le LogInfo farai semplicemente:
ctx.Log.OfType<LogInfo>();


Nell'articolo, il mapping è realizzato usando dei data attributes. Volendo puoi fare il mapping anche da interfaccia fluente come vedi qui:
https://weblogs.asp.net/manavi/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part-2-table-per-type-tpt

ciao,
Moreno
Modificato da BrightSoul il 04 ottobre 2017 20.27 -

Enjoy learning and just keep making
9 messaggi dal 09 novembre 2016
Ciao Moreno,

grazie della risposta, ma non penso si possa applicare al mio caso.

Questo perchè la mia classe LogInfo non è una tabella fisica sul db ma una classe che estende quella base Log con una proprietà che dovrebbe essere popolata con una join verso la tabella LogActions (dalla quale leggere il valore ActionName).

Provando infatti la soluzione che mi hai suggerito viene generata un'eccezione: 'LogInfo' non è un tipo di metadati valido per le operazioni di filtro dei tipi. Le operazioni di filtro dei tipi sono valide solo su tipi di entità e tipi complessi
(infatti non vedo come possa funzionare visto che rispetto all'esempio non ho la stessa situazione).

Magari le indicazioni che ho dato nel post non sono chiare?
11.886 messaggi dal 09 febbraio 2002
Contributi
Ciao,
che tipo di relazione esiste tra Log e LogActions? 1-a-1? 1-a-molti? Qual è la principale e qual è la dipendente tra le due?

ciao,
Moreno

Enjoy learning and just keep making
9 messaggi dal 09 novembre 2016
Ciao

la relazione è 1-a-molti.

LogActions:
ActionID
Name

Logs:
LogID
ActionID
..

Una struttura quindi molto semplice.
9 messaggi dal 09 novembre 2016
Riquoto

AlexNap ha scritto:
Ciao

la relazione è 1-a-molti.

LogActions:
ActionID
Name

Logs:
LogID
ActionID
..

Una struttura quindi molto semplice.
11.886 messaggi dal 09 febbraio 2002
Contributi
Ciao,


la relazione è 1-a-molti.

Ok, allora non puoi usare i modelli di ereditarietà di cui ti ho parlato. Mi aveva tratto in inganno il termine "classe estesa". I modelli di ereditarietà supportati da entity framework funzionano sulla stessa tabella o su altre tabelle relazionate 1-a-1.

Invece, puoi fare in modo che la proprietà Log di LogInfo sia una proprietà di navigazione, e questo ti eviterà di fare una join esplicita come quella che hai postato.
In pratica, tramite mapping, indichi ad entity framework che esiste una relazione 1-a-molti tra Log e LogInfo e perciò saprà che deve recuperare i dati da un'altra tabella quando vai a leggere il contenuto della proprietà Log.

Leggi questi articoli per capire cosa sono le proprietà di navigazione e come mapparle.
https://coding.abel.nu/2012/06/dont-use-linqs-join-navigate/
http://www.entityframeworktutorial.net/code-first/configure-one-to-many-relationship-in-code-first.aspx

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.