Come organizzare le query predefinite con Entity Framework?

6

Ho alcune query che uso sempre (come ottenere solo righe di un tipo specifico, o contare qualcosa ecc.). Mi piacerebbe organizzarli in qualche modo (meglio di quello che faccio attualmente).

Attualmente li ho tutti in un static class chiamato Queries che non mi piace molto perché è come un non-so-come-a-dire-questa-classe .

Esiste un modo preferito per organizzare query predefinite in Entity Framework estendendo alcuni tipi ecc.?

Come richiesto qui c'è un esempio che mostra come lo utilizzo:

Tutte le mie query:

public static class Queries
{
    public static IEnumerable<Light> GetEnabledLights()
    {
        using(var context = new MyEntities())
        {
             return context.Lights.Where(l => l.Enabled);
        }
    }
}

Codice che utilizza alcune query:

public static class LightsLoader
{
    public static void LoadLights()
    {
        var enabledLights = Queries.GetEnabledLights().ToList();
        if (enabledLights.Count == 0)
        {
            throw new InvalidOperationException("There are no enabled lights.");
        }
        // ... more code
    }
} 

Falso interrogativo e test della logica aziendale:

[TestClass]
public class LightsLoaderTests
{
    [TestMethod]
    [ExpectedException(typeof(InvalidOperationException))]
    public void TestNoEnableLights()
    {
        using(ShimContext.Create())
        {
            ShimQueries.GetEnabledLights = () => Enumerable.Empty<Light>();
            LightsLoader.LoadLights();
        }
    }
}

Ma torniamo alla domanda: pensavo che Entity Framework potesse offrire un modo migliore per organizzare le query e metterle tutte in una God-Class; -)

    
posta t3chb0t 03.03.2015 - 14:42
fonte

2 risposte

3

Estendere il contesto ORM è un buon approccio, ma in un sistema con molte query predefinite, utilizzo un altro approccio, usando i metodi Estensioni per raggruppare le query correlate. Lasciatemi fare un esempio:

L'utilizzo è semplice come questo:

var data = Context.Financial() // This returns a FinancialContextExtensions instance with all Financial grouped queries
                  .GetComplexReportData() // This returns the actual result for your query
                  .ToArray();

Creo un file FinancialContextExtensions :

public static partial class ContextQueryExtensions
{
    public static FinancialContextExtensions Financial(this DataContext context)
    {
        return new FinancialContextExtensions(context);
    }
}

public class FinancialContextExtensions : ContextExtensions
{
    protected readonly DataContext Context;

    public FinancialContextExtensions(DataContext context)
    {
        this.Context = context;
    }

    public IEnumerable<FinancialReportInfo> GetComplexReportData(DateTime dateBeing, DateTime dateEnd)
    {
        return from a in Context.AAA
               join b in Context.BBB on ...
               where ...
               group ...
               select new FinancialReportInfo { ... };
    }
}

PS: non so se questo modello ha un nome, ma ricordo che lo ho letto su un sito, non so quale sito, però ...

    
risposta data 03.03.2015 - 22:07
fonte
1

Sembra che tu stia organizzando il tuo codice in base a quale sia il codice e non al dominio a cui si applica. Come sviluppatore che lavora con il framework entità, mi aspetto che tu abbia una classe derivata DataContext con tutte le tue operazioni generali CRUD. Dato che questo DataContext è il tuo gateway per il database, avrebbe senso memorizzare le query e i metodi che li utilizzano nella tua classe derivata. Suggerisco di non esporre pubblicamente le stringhe della query letterale, di mantenerle riservate e di creare metodi pubblici che li utilizzano internamente.

    
risposta data 03.03.2015 - 17:13
fonte

Leggi altre domande sui tag