Поиск указателей на уровне базы данных-абстракции - PullRequest
0 голосов
/ 17 ноября 2010

Начну с того, что в течение нескольких проектов я реализовал это двумя различными способами, но никогда не был удовлетворен результатами.

ПРИМЕЧАНИЕ: я не заинтересован в использовании ORMS!

Фон

Я работал над многими проектами, для которых требовался уровень абстракции базы данных для нескольких платформ. Еще во времена классического ASP / VBScript у нас был набор функций, которые инкапсулировали текст SQL для очистки данных, а затем строили строку, подходящую для провайдера (SQL Server, MSSQL, Oracle, DB2 и так далее).

Забегая вперед несколько лет назад, я написал DAL, который заменил все эти извилистые струнные вещи на реальные объекты. Идея была проста: вы вывели класс базы данных из абстрактного класса Database для обработки открытия / закрытия и выполнения вещей в соответствии с провайдером .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 и т. Д.).

1 Ответ

1 голос
/ 17 ноября 2010

Играли ли вы вообще с LINQ to SQL? Это на самом деле не полнофункциональный ORM, но он представляет собой беглую модель для представления операций базы данных. Даже если вы не хотите использовать LINQ to SQL, вы можете написать свой собственный поставщик LINQ, который вам больше по вкусу. Это дает преимущество в том, что разработчики, уже знакомые с LINQ, могут использовать вашу систему без особого дополнительного обучения. Если вы еще не знакомы, прочтите Деревья выражений . LINQ был разработан в значительной степени для того, чтобы выполнять именно то, что вы описываете, и была проделана большая работа для обеспечения очень гибкого и естественного представления запросов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...