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:
- Non aggiunge ulteriore astrazione
- 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.
- 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.
- Diventa anche possibile fare alcune query generiche, come ad esempio:
GetPersonbyName<TPerson>(string firstName, stringLastName) where TPerson : Person
, forse contenuto in una classePersonsQuery
.
Contro
- 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 .
- Forse altri? Non ne sono sicuro.
Esistono altri svantaggi nell'usare questo stile per il riutilizzo del codice senza astrazioni ridondanti?