Лучший способ сделать запрос к различным механизмам баз данных единообразным способом? - PullRequest
2 голосов
/ 25 февраля 2010

Я работаю над клиентским приложением C # ( SlimTune Profiler ), которое использует механизмы реляционных (и потенциально встроенных) баз данных в качестве своего резервного хранилища. Текущая версия уже имеет дело с SQLite и SQL Server Compact, и я хотел бы поэкспериментировать с поддержкой других систем, таких как MySQL, Firebird и так далее. Хуже того, я бы хотел, чтобы он поддерживал плагины для любого другого резервного хранилища данных - и не обязательно те, которые в идеале основаны на SQL. Завершая процесс, сам интерфейс поддерживает плагины, поэтому у меня есть неизвестное сопоставление «многие ко многим» между запросом кода и механизмами, обрабатывающими запросы.

В настоящее время запросы в основном обрабатываются с помощью необработанного кода SQL. Я уже столкнулся с проблемами, заставляя сложные SELECT работать портативно. Со временем проблема может только усугубиться, и это даже не учитывает идею поддержки данных, отличных от SQL. Итак, каков наилучший способ опрашивать дико разрозненные движки разумным способом?

Я рассмотрел что-то на основе LINQ, возможно, проект DbLinq . Другой вариант - это постоянные объекты, например, Subsonic . Но я не слишком уверен, что там, каковы ограничения, или я просто надеюсь на слишком много.

(Кроме того, из-за неизбежного вопроса о том, почему я не остановлюсь на одном движке. Мне нравится давать пользователю выбор механизма, который лучше всего работает для него. SQL Compact позволяет выполнять репликацию на полный экземпляр SQL Server. SQLite является переносимым и поддерживает базы данных в памяти. Я могу представить себе ситуацию, когда компания хочет добавить плагин MySQL, чтобы они могли с легкостью хранить и сопоставлять данные о производительности приложения с течением времени. И, наконец, самое главное, я нахожу Идея, что я должен зависеть от деталей реализации моего базового движка базы данных, абсурдна.)

Ответы [ 3 ]

2 голосов
/ 25 февраля 2010

Лучше всего использовать интерфейс для доступа ко всем базам данных. Затем для каждого типа базы данных, которую вы хотите поддержать, выполните реализацию интерфейса для этой базы данных. Это то, что я должен был сделать для проектов в прошлом.

Проблема многих систем баз данных и инструментов хранения заключается в том, что они направлены на решение различных проблем. Возможно, вы даже не захотите хранить свои данные в базе данных SQL, а вместо этого сохраните их в виде файлов в папке App_Data веб-приложения. С помощью метода интерфейса вы можете сделать это довольно легко.

Как правило, не существует решения, которое бы подходило всем решениям для баз данных и систем хранения или даже нескольким из них. Если вы найдете тот, который утверждает, что это делает, я все равно не буду доверять этому. Когда у вас возникнут проблемы с одной из баз данных, вам будет намного легче копаться в ваших объектах, чем копаться в них.

1 голос
/ 25 февраля 2010

Используйте объектно-реляционный маппер. Это обеспечит высокий уровень абстракции от различных механизмов баз данных и не будет накладывать (много) ограничений на тип запросов, которые вы можете запускать. Многие ORM также включают поддержку LINQ. Есть много вопросов о том, как SO предоставляет рекомендации и сравнения (например, Какой ваш любимый ORM для .NET? , кажется, самый последний и имеет ссылки на несколько других).

0 голосов
/ 25 февраля 2010

Я бы порекомендовал шаблон хранилища. Вы можете создать класс, который инкапсулирует все действия, для которых вам нужна база данных, а затем создать отдельную реализацию для каждого типа базы данных, который вы хотите поддерживать. Во многих случаях для реляционных хранилищ данных вы можете использовать абстракции ADO.NET (IDbConnection, IDataReader, IDataAdapter и т. Д.) И создать единый общий репозиторий, а также писать только конкретные реализации для типов баз данных, которые не предоставляют ADO.NET. драйвер.

public interface IExecutionResultsRepository
{
  void SaveExecutionResults(string name, ExecutionResults results);
  ExecutionResults GetExecutionResults(int id);
}

Я на самом деле не знаю, что вы храните, поэтому вам придется адаптировать это для ваших реальных потребностей. Я также предполагаю, что это потребует некоторого серьезного рефакторинга, поскольку у вас могут быть помечены SQL-выражения в вашем коде. И вытащить их и заключить их в капсулу может быть неосуществимо. Но ИМО, это лучший способ достичь того, что вы хотите сделать.

...