Если использовать ORM, то ответ очевиден. Вы будете использовать встроенные в них средства, а также бороться с их ограничениями.
В принципе же, ответ таков: выделять классический DAL — Data Access Layer. Для этого существует много стандартных паттернов. Например:
Самое простое — Data Mapper. Создаёте интерфейс для вашей сущности:
interface ICarData
{
void Insert(Car car);
Car GetById(int id);
// и т.д.
}
Затем наследуете от этого интерфейса классы, его реализующие — e.g. MySqlCarData, MongDbCarData.
Отдельная задача здесь — определение, какой класс использовать. Самый простой способ — задавать имя класса через конфигурационный файл и создавать объект нужного класса простой фабрикой (switch(className) {… } ). Более красиво — использовать IoC/DI контейнер.