C # DbContext con classi nidificate contenenti i metodi Repository

1

Quindi ho letto molto e sembra che, dal momento che DbContext implementa già una combinazione di schemi di repository e unità di lavoro, la creazione di più classi di astrazione sarebbe ridondante. Tuttavia, mi piacerebbe ancora essere in grado di incapsulare query di uso comune per il riutilizzo del codice. Stavo pensando - forse potrei essere in grado di memorizzare una classe contenitore di query che utilizza l'istanza corrente di DbContext per assicurarsi che le query non superino i limiti delle transazioni. Prendi ad esempio questo codice fittizio:

public partial class PersonEntities : DbContext
{
    public PersonEntities() : base("name=SomeConnectionString")
    {
        this.Configuration.ProxyCreationEnabled = false;
        this.CustomersQuery = new CustomerQueries(this);
    }

    public virtual DbSet<Customer> Customers { get; set; }
    public virtual DbSet<Employees> Employees { get; set; }

    public CustomerQueries CustomersQuery { get; }

    public class CustomerQueries 
    { 
        protected PersonEntities Database { get; private set; }

        internal CustomerQueries(PersonEntities db)
        {
            this.Database = db;
        }

        public IEnumerable<Customer> GetCustomersByName(string firstName, string lastName, bool ignoreCase = true)
        {
            /// method implementation
        }
    }
}

Potresti usarlo in questo modo (classi concrete e mancanza di fabbriche per semplificazione):

        using (var context = new PersonEntities())
        {
            var query = context.CustomersQuery.GetCustomersByName("Alfred", "Morris", true);

            /// stuff

            await context.SaveChanges();
        }

Pro:

  1. Non aggiunge ulteriore astrazione
  2. Le query possono utilizzare più DbSet contemporaneamente all'interno della stessa transazione, diversamente da molti degli implementatori di repository (in particolare repository generici) che ho visto.
  3. Le query correlate sono ordinatamente contenute in un unico posto con metodi prevalentemente rilevanti (oltre ai metodi di oggetti comuni come ToString), nel frattempo la classe DbSet stessa ha tonnellate di metodi grazie ai metodi di estensione IEnumerable / IQueryable / etc e quindi estendendo DbSet didn ' t mi sembra una buona idea.
  4. Diventa anche possibile fare alcune query generiche, come ad esempio: GetPersonbyName<TPerson>(string firstName, stringLastName) where TPerson : Person , forse contenuto in una classe PersonsQuery .

Contro

  1. Aggiunge funzionalità aggiuntive che potrebbero essere considerate eccessive, potenzialmente portando a una "classe di Dio" - tuttavia, queste query sono ancora strettamente accoppiate ai DbSet e sono ancora in sottoclassi, quindi non sono sicuro se questo è il caso .
  2. Forse altri? Non ne sono sicuro.

Esistono altri svantaggi nell'usare questo stile per il riutilizzo del codice senza astrazioni ridondanti?

    
posta NotJehov 15.09.2015 - 23:12
fonte

1 risposta

1

Per questo tipo di cose mi piace utilizzare i metodi di estensione C # contro IQueryable < & gt ;. Avresti comunque una classe a definirli ma non sarebbe annidata o referenziata dal tuo contesto.

Esempio:

public static class IQueryableOfCustomerExtensions
{
    public static IQuerable<Customer> GetByName(this IQueryable<Customer> customers, string firstName, string lastName, bool ignoreCase = true)
    {
        // Implementation
    }
}

Potresti quindi chiamarlo così:

var customers = context.Customers.GetByName("Alfred", "Morris", true).ToList();
    
risposta data 16.09.2015 - 14:14
fonte

Leggi altre domande sui tag