Начну с того, что в ходе нескольких проектов я реализовал это двумя разными способами, но никогда не был удовлетворен результатами.Поиск указателей на уровне абстракции базы данных
ПРИМЕЧАНИЕ: Я принимаю , а не, заинтересованные в использовании ORMS!
Фоновый
Я работал над многими проектами, которые требовали базы данных-абстракции слоя для нескольких платформ. Еще во времена классического ASP/VBScript у нас был набор функций, которые инкапсулировали текст SQL для очистки данных, а затем строят строку, подходящую для провайдера (SQL Server, MSSQL, Oracle, DB2 и т. Д.).
Ускоренная перемотка вперед, несколько лет назад, я написал DAL, который заменил весь этот свернутый материал струны на реальные объекты. Идея была простой: вы получили класс базы данных из абстрактного класса базы данных для обработки открытия/закрытия и выполнения вещей в соответствии с поставщиком .NET. Также были сделаны Insert
, Select
, Update
объектами, которые также надлежащим образом работали для провайдера. По правде говоря, хотя это сработало, и программное обеспечение могло работать с любой базой данных через объекты, а программисту никогда не приходилось касаться SQL; это было громоздко. Представление новой платформы базы данных потребовало времени для создания всех объектов.
Пример кода:
DB.Database db = DatabasePool.Get();
try
{
DB.Select select = db.NewSelect("_people"); // MSSQL/Oracle/DB2, doesn't matter
select.Add("_id");
select.Add("_people_name");
select.Where.AndClause("_people_name", DB.Operator.Like, "bob");
DB.Results results = select.ExecuteToCollection();
// here, Select is "tailored" to the right DB provider and returns the correct
// sql.
}
finally
{
DatabasePool.Release();
}
Следующая итерация улучшилась на это несколько. Вместо того, чтобы иметь абстрактный класс базы данных и целую кучу абстрактных объектов для представления операций, существовал набор конкретных объектов. Затем провайдеры предоставили делегат для каждого типа. Преобразование объектов в SQL было простым случаем бросания его на Dictionary<Type, Delegate>
, и провайдер знал, как преобразовать этот конкретный объект (или, действительно, интегральный тип) в SQL, одновременно выполняя очистку данных. Все было хорошо, и я улучшил аксессор к объектам:
DB.Database db = DatabasePool.Get();
try
{
DB.Select select = new Select(db); // now a sealed, concrete object
select.Add("_id").Add("_people_name");
select.Where.And("_people_name", DB.Op.Like, "bob");
DB.Results results = select.Query();
// much better now. Select is a sealed object. The Database class has a bunch of
// delegates that convert any type (including Select, Delete, int, decimal) to
// appropriate SQL. Much less work implementing different providers.
}
finally
{
DatabasePool.Release();
}
Теперь
У меня есть возможность сейчас, чтобы сделать это снова (и проект-время, чтобы сделать это). Я предполагаю, что мой вопрос заключается в том, что это хороший способ управления различными провайдерами, инкапсулирующими операции с базами данных в объектах? В то время как делегаты работают отлично:
1) Легко написать генератор для Column
, Select
, Delete
, int
, NULL
, всякая всячина, но при построении WHERE
положения, я в конечном итоге с кучей крошечных атомных объектов, которые сделали «части ' вещей.
2) В то время как разные ароматы SQL имеют тонкие различия, большинство из них одинаково. Класс base-database обеспечивал приемлемые значения по умолчанию для почти всех объектов, а разные поставщики просто заменяли этих делегатов. Но я не видел это очень «ясным» для программиста. Неясно, какие из них были обработаны тем слоем кода.
Есть ли лучший способ? Я доволен концепцией объектов, заменяющих запись любого SQL вообще. Они упрощают создание SQL-предложений динамически, с очисткой и соответствующим преобразованием типов из типа базы данных в тип .NET (например, я никогда не имел дело с типами баз данных вне объектов базы данных.Я всегда получаю DateTime назад, System.UInt32, bool и т. Д.).
Спасибо за это, я посмотрю на это. Как это также будет обрабатывать инкапсуляцию создания/изменения таблиц/столбцов, удалений, вставок и обновлений? DAL, который я сделал, предоставил объекты для выполнения всех этих задач, не беспокоясь о базовом синтаксисе. –
LINQ может представлять только часть запроса этих операторов, поэтому вам нужно определить собственный механизм для интерпретации запроса в контексте DELETE или UPDATE, например (конструктор запроса по-прежнему очень полезен для указания того, что DELETE и который записывает в UPDATE.) –
Привет, Dan, я делал немного копания, и я разбавлял LINK, который мог бы приятно удовлетворить части WHERE моих объектов, и что интеграция этих двух может быть здесь. Я предполагаю, что мой последний вопрос в этом вопросе, учитывая запросы LINQ, которые я вижу здесь постоянно, как это преобразуется в SQL в настоящее время, и есть ли уже слой абстракции для работы с разными провайдерами? Благодаря! :) –