Cześć, problem jest taki. Załóżmy, że aplikacja może pracować zarówno na MSSQL, MySQL(MariaDB), jak i SQLite. I tak faktycznie będzie pracować. I teraz pytanie, jak to ogarnąć nie używając ORMa.
Chodzi mi o to, że mam sobie jakąś klasę bazową, np(pseudokod):
abstract class DatabaseEngine
{
IDbConnection connection;
public DatabaseEngine(IDbConnection connection)
{
this.connection = connection;
}
public void Connect(string connectionString)
{
connection.Open(connectionString);
}
//i jakieś metody do wywoływania zapytań w stylu ExecuteQuery, SelectSQL, obsługa transakcji itd.
}
Teraz mam klasy, które po tym dziedziczą:
class MSSQLDb: DatabaseEngine
{
public MSSQLDb(): base(new MSSQLConnection())
{
}
}
class MySQLDb: DatabaseEngine
{
public MySQLDb(): base(new MySQLConnection())
{
}
}
class SQLiteDb: DatabaseEngine
{
public SQLiteDb(): base(new SQLiteConnection())
{
}
}
I fajnie. Mam teraz np. takie repozytorium:
class PersonRepository: Repository<Person>
{
DatabaseEngine dbContext; //jakoś to przekazuję
public List<Person> GetAll()
{
}
}
I teraz tak. W metodzie GetAll powinienem wywołać jakiegoś SQL. Ale problem jest taki, że na różnych DBMS ten SQL może wyglądać nieco inaczej. Np.
MSSQL:
SELECT pole1, pole2, pole3
FROM tabela
MySQL:
SELECT jakas_funkcja(pole1) as pole1, pole2, pole3
FROM tabela
Itd. Jak to pogodzić? W jaki sposób zaprojektować taki system? Chciałbym uniknąć duplikowania zapytań, ale nie za bardzo wiem jak to zaprojektować. Jedyny pomysł na jaki wpadłem to użycie procedur składowanych. Ale... SQLite nie ma procedur składowanych ;)
Nie mam pomysłu, jak to DOBRZE zaprojektować. Próbuję wymyślić coś z jakąś dodatkową warstwą, ale nie za bardzo widzę to póki co. Jakieś sugestie?