2013-06-07 12 views
13

Sto cercando di capire le basi di Entity Framework e ho una domanda sul metodo Set < su DbContext. Sto usando un primo modello di database per la seguente domanda.Entity Framework: Quando utilizzare Set <>

Diciamo che ho un database ActivityLog che tra le altre cose posso utilizzare per estrarre un messaggio (messaggio NLog, ad esempio). Potrei scrivere del codice per tirare fuori tutti i messaggi come questo:

using (var entities = new ActivityLogEntities()) 
    foreach (var log in entities.AcitivityLogs) 
     Console.WriteLine(log.Message); 

Tuttavia ho potuto anche ottenere la stessa cosa facendo questo:

using (var entities = new ActivityLogEntities()) 
    foreach (var message in entities.Set<ActivityLog>().Select(entity => entity.Message)) 
     Console.WriteLine(message); 

La mia domanda è che cosa è la differenza tra queste due affermazioni? Quando è più appropriato usare l'uno sull'altro? O è solo una questione di preferenze personali?

+1

Se non si dispone di una proprietà 'ActivityLogs', non è possibile utilizzare la proprietà' ActivityLogs'. Potrebbe sembrare una risposta inutile, ma ho avuto situazioni in cui avevo bisogno di accedere a 'DbSet ' per un tipo che intenzionalmente non aveva una proprietà diretta per le entità di quel tipo. Ma questo non risponde alla domanda su quale usare quando entrambi sono possibili. – hvd

+0

@hvd è d'accordo ma è piuttosto raro avere tipi non referenziati dal contesto (e non è del tutto banale da fare) –

+0

@LukeMcGregor Considera 'public class Order {public ICollection Lines {get; impostato; }} public class OrderLine {} classe pubblica Context {public IDbSet Orders {get; set privato; }} '. Non è necessario alcun lavoro supplementare per fare in modo che funzioni, e di solito non ha senso accedere a 'OrderLines' senza gli ordini, quindi perché dovrei aggiungere una proprietà' OrderLines' a livello di contesto? – hvd

risposta

10

Non c'è alcuna differenza significativa. Nel primo caso, si ha qualcosa di simile:

class MyContext : DbContext 
{ 
    public DbSet<AcitivityLog> AcitivityLogs { get; set; } 
} 

quando il contesto è la creazione, sembra per pubblici DbSet<T> lettura/riprese di proprietà, e fa questo (pseudo-codice):

dbSetProperty = Set<EntityType>(); 

Ma , ci sono casi in cui:

1) non si desidera rendere proprietà pubbliche per tutti i tipi di entità;
2) non conosco tutti i tipi di entità al momento della progettazione del contesto.

In questi casi, Set<T> è l'unico modo per ottenere il set di entità appropriato.

+0

Suppongo che nel caso del tuo secondo esempio ciò si applichi solo all'automatico generato? – Serberuss

+0

@Serberuss: no, non solo. Uno dei vantaggi dell'API 'DbContext' è la possibilità di costruire il contesto in modo dinamico (al contrario dell'approccio tradizionale con' ObjectContex' e il progettista EDM). Ciò consente di costruire un modello di dati molto più flessibile, ma ha un effetto collaterale: l'elenco dei tipi di entità non è statico e lo sviluppatore di un antenato 'DbContext' non può sapere su ogni tipo di entità. – Dennis

+0

Sfortunatamente il secondo esempio non funziona. Ho seguito un tipo di errore: 'L'entità non fa parte del modello per il contesto attuale. Non ho idea di cosa sto facendo male. – krypru

1

Se il vostro sguardo al generata DbContext classe vedrai che AcitivityLogs è solo un DbSet<ActivityLog>.

Quindi sono la stessa cosa. È solo la definizione tipizzata del tuo DbSet.

8

L'unico motivo per cui ho utilizzato lo Set<T> è quando si agisce su un tipo che non si conosce, ad esempio un inserto generico.

Ecco un esempio da my generic repository:

public void AddOnSave(T entity) 
    { 
    ctx.Set<T>.Add(entity); 
    } 

Usandolo per roba regolare solo rende il codice meno leggibile IMHO

+0

['AddOrUpdate'] (https://msdn.microsoft.com/en-us/library/dn217945 (v = vs.113) .aspx)? – oCcSking

+0

@oCcSking non sei sicuro di cosa intendi? –

+0

In realtà, non ho capito la tua risposta correttamente, confuso con il caso non sei sicuro se aggiungerai o aggiorni, allora puoi usare AddOrUpdate – oCcSking

Problemi correlati