2010-11-17 4 views
0

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

ПРИМЕЧАНИЕ: Я принимаю , а не, заинтересованные в использовании 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 и т. Д.).

ответ

1

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

+0

Спасибо за это, я посмотрю на это. Как это также будет обрабатывать инкапсуляцию создания/изменения таблиц/столбцов, удалений, вставок и обновлений? DAL, который я сделал, предоставил объекты для выполнения всех этих задач, не беспокоясь о базовом синтаксисе. –

+0

LINQ может представлять только часть запроса этих операторов, поэтому вам нужно определить собственный механизм для интерпретации запроса в контексте DELETE или UPDATE, например (конструктор запроса по-прежнему очень полезен для указания того, что DELETE и который записывает в UPDATE.) –

+0

Привет, Dan, я делал немного копания, и я разбавлял LINK, который мог бы приятно удовлетворить части WHERE моих объектов, и что интеграция этих двух может быть здесь. Я предполагаю, что мой последний вопрос в этом вопросе, учитывая запросы LINQ, которые я вижу здесь постоянно, как это преобразуется в SQL в настоящее время, и есть ли уже слой абстракции для работы с разными провайдерами? Благодаря! :) –

Смежные вопросы