Attualmente sto creando un'applicazione per Windows utilizzando sqlite. Nella base dati c'è una tabella che dice User
, e nel mio codice c'è un Repository<User>
e un UserManager
. Penso che sia un design molto comune. Nel repository c'è un metodo List
:ritorno Queryable <T> o Elenco <T> in un repository <T>
//Repository<User> class
public List<User> List(where, orderby, topN parameters and etc)
{
//query and return
}
Questo porta un problema, se voglio fare qualcosa di complesso in UserManager.cs
:
//UserManager.cs
public List<User> ListUsersWithBankAccounts()
{
var userRep = new UserRepository();
var bankRep = new BankAccountRepository();
var result = //do something complex, say "I want the users live in NY
//and have at least two bank accounts in the system
}
Si può vedere, il ritorno List<User>
porta problema di prestazioni, becuase il la query viene eseguita prima del previsto. Ora ho bisogno di cambiarlo in qualcosa di simile a un IQueryable<T>
:
//Repository<User> class
public TableQuery<User> List(where, orderby, topN parameters and etc)
{
//query and return
}
TableQuery<T>
fa parte del conducente SQLite, che è quasi uguale a IQueryable<T>
in EF, che fornisce una query e non verrà eseguito immediatamente. Ma ora il problema è: nel UserManager.cs
, non sa cosa sia un TableQuery<T>
, ho bisogno di aggiungere nuovo riferimento e importare spazi dei nomi come using SQLite.Query
nel progetto del livello aziendale. Porta davvero brutte sensazioni al codice. Perché il mio livello aziendale dovrebbe conoscere i dettagli del database? perché il livello aziendale dovrebbe sapere cos'è SQLite? Qual è il design corretto allora?
Potrebbe non "solo" aggiungere un nuovo strato di astrazioni (interfacce) tra il livello di business e lo strato di accesso ai dati? Sì, ciò richiederebbe un nuovo set di oggetti che rappresentano gli stessi dati nel livello aziendale e il mapping tra questi e quelli nel livello DA - in un certo senso, la duplicazione del codice - ma dovrebbe fornire un taglio più pulito tra i livelli, se Capisco correttamente la tua situazione. – Kjartan
Sono d'accordo con @Kjartan, cosa vuoi veramente è IQueryable, è un peccato che SQLite non ne abbia uno, vale la pena creare un altro livello da trasferire per correggere il tipo. –
ivenxu
@Kjartan @ivenxu: non ho detto 'TableQuery' non è corretto, né 'IQueryable ' è corretto. Anche io ho aggiunto una nuova interfaccia di trasferimento, come 'IQuery ', è ancora * base su * 'TableQuery ', e quando uso 'IQuery ' nel mio livello aziendale, tutto è lo stesso. Semplicemente * sembra * non correlato con SQLite, ma in realtà indossa una maschera. –