Come faccio a riscrivere le espressioni di query per sostituire le enumerazioni con ints?

c# entity-framework entity-framework-4.1 expression-trees reflection

Domanda

Ispirato dal desiderio di poter usare le enumerazioni nelle query EF, sto considerando l'aggiunta di un ExpressionVisitor ai miei repository che prenderà in considerazione i criteri dei criteri e delle richieste in arrivo e li riscriverò per utilizzare la proprietà int persistente corrispondente.

Uso costantemente il seguente modello di suffisso di valore nelle mie entità (in ordine di codice):

public class User : IEntity
{
    public long ID { get; set; }

    internal int MemberStatusValue { get; set; }

    public MemberStatus MemberStatus 
    {
        get { return (MemberStatus) MemberStatusValue; }
        set { MemberStatusValue = (int) value; }
    }
}

E mappare questo al database utilizzando il seguente:

internal class UserMapping : AbstractMappingProvider<User>
{
    public override void DefineModel( DbModelBuilder modelBuilder )
    {
        // adds ToTable and other general mappings
        base.DefineModel( modelBuilder );

        Map.Property( e => e.MemberStatusValue ).HasColumnName( "MemberStatus" );
    }
}

Nei miei repository ho il seguente metodo:

public IQueryable<T> Query( Expression<Func<T, bool>> filter, params string[] children )
{
    if( children == null || children.Length == 0 )
    {
        return Objects.Where( filter );
    }
    DbQuery<T> query = children.Aggregate<string, DbQuery<T>>( Objects, ( current, child ) => current.Include( child ) );
    return filter != null ? query.Where( filter ) : query;
}

Vorrei aggiungere una chiamata al metodo all'interno di questo metodo per riscrivere l'espressione del filtro, sostituendo tutti i riferimenti alla proprietà MemberStatus con riferimenti a MemberStatusValue.

Suppongo che sarà una soluzione che coinvolge qualcosa come visto in questo post SO , ma non sono sicuro esattamente come passare dall'idea all'implementazione.

Se puoi dare qualche consiglio sul potenziale impatto delle prestazioni dell'aggiunta di questa funzione, sarebbe anche apprezzato.

Risposta popolare

Non sono sicuro che sia proprio quello che cerchi, ma ho trovato più semplice gestire le enumerazioni in modo simile ma leggermente diverso. A proposito, ho due proprietà, come fai tu, ma la mia proprietà int è pubblica ed è ciò che persiste nel database; Poi ho un'altra proprietà pubblica "wrapper" che ottiene / imposta il valore della proprietà int tramite i cast da / al tipo enumerato desiderato, che è ciò che viene effettivamente utilizzato dal resto dell'applicazione.

Di conseguenza, non devo scherzare con il modello; EF comprende e persiste bene la proprietà int mentre il resto dell'applicazione ottiene buone interazioni con il tipo enum. L'unica cosa che non mi piace del mio approccio è che devo scrivere le mie istruzioni LINQ con un gruppo di cast su qualsiasi valore enum che sto cercando di interrogare per trasformarlo in un int in modo che corrisponda al campo che è effettivamente persistente. È un piccolo prezzo, tuttavia, e mi piacerebbe suggerirtelo perché mi sembra che tu stia usando una stringa per generare la tua query che cede tutto il tipo di sicurezza, Intellisense, ecc. Che LINQ fornisce.

Infine, se sei interessato a una panoramica su come utilizzare le nuove funzionalità enum in EF 5 (che è disponibile in versione beta per il download ora se vuoi provarlo), controlla questo:

http://msdn.microsoft.com/en-us/hh859576



Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché