Проектное решение: (VB.NET) Должен ли я создать класс или модуль для простого подключения к одной из многих баз данных?

По сути, у нас есть три базы данных для сбора данных. Одна из них - база данных SQL Server, другая - база данных Access (которая особенно раздражает при подключении, потому что нам необходимо подключить сетевой диск и т. Д.), А последней будет база данных Oracle, когда ИТ-отдел наконец предоставит нам права.

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

Dim myEasyResultArray(10,10) as String
myEasyResultArray = DatabaseHelper("Access", "SELECT * FROM Employee")

Это хорошее дизайнерское решение? Кроме того, как я могу получить массив нужного размера? Могу я просто сделать это?

Dim myEasyResultArray = DatabaseHelper("Access", "SELECT * FROM Employee")

Это должен быть модуль или класс? Мне не нужно обмениваться переменными,

 user11451811 июн. 2012 г., 15:48
Это второй сценарий: программа будет запрашивать одну или несколько баз данных во время выполнения веб-страницы (но им не нужно одновременно), и я не знаю, какая из них до времени выполнения
 tcarvin11 июн. 2012 г., 15:43
Вы намерены иметь программу, которая запрашивает базу данных одновременно, или программу, которая запрашивает одну базу данных из трех возможных баз данных, но вы не знаете, какая из них до времени выполнения?
 user11451811 июн. 2012 г., 16:00
Ой! Нам нужно иметь только одно открытое соединение одновременно для любого конкретного пользователя.
 tcarvin11 июн. 2012 г., 15:57
У меня был плохой выбор слов, я не имел ввиду одновременно в конкретном (многопоточном или подобном) смысле слова, я имел в виду это при использовании множественных соединений против одного соединения, но мы не делаем этого. -знаю-какой-до-во-смысл смысла слова. Ясно, как грязь, я знаю :) Но я думаю, что теперь у меня есть твоя суть

Ответы на вопрос(2)

Решение Вопроса

а к данным. В идеале это должно быть в отдельной библиотеке и пространстве имен, но это не обязательно. Я бы использовал классы, обычно по одному на таблицу / сущность, и спроектировал бы, чтобы все классы были без сохранения состояния (так что вам больше не нужно повторно использовать один и тот же экземпляр объекта доступа к данным, вы можете просто создать новый экземпляр в любое время, когда вам понадобится доступ к БД).

Вместо того, чтобы возвращать массивы, я бы возвращал объекты данных (часто называемые DTO - объекты передачи данных). Я хотел бы сохранить классы DTO настолько чистыми, насколько это возможно, содержащие только открытые свойства и никакие методы, если это возможно. Все классы доступа к данным должны реализовывать интерфейсы, чтобы можно было создать несколько версий каждого из них. Один для Access, один для Oracle, один для SQL и т. Д. Затем, где бы мне ни понадобился доступ к базе данных (надеюсь, только на моем бизнес-уровне, а не на уровне UI), я запрашивал соответствующие объекты доступа к данным по их & quot ; общий & Quot; тип интерфейса (тем самым требуется, чтобы фабричный класс вводил правильный тип объекта доступа к конкретным данным в мой бизнес-объект).

Вот очень простой пример DTO:

Public Class Employee
    Public Id As Guid
    Public Name As String
    Public StartDate As Date
End Class

Вот пример интерфейса доступа к данным

Public Interface IEmployeeDataAccess
    Function GetEmployee(id As Guid) As Employee
    Function GetEmployees() As List(Of Employee)
End Interface

Вот пример класса доступа к данным:

Public Class SqlEmployeeDataAccess
    Inherits IEmployeeDataAccess

    Public Function GetEmployee(id As Guid) As Employee Implements IEmployeeDataAccess.GetEmployee
        Dim employee As New Employee()
        ' Connect to SQL DB and populate employee DTO object
        Return employee
    End Function

    Public Function GetEmployees() As List(Of Employee) Implements IEmployeeDataAccess.GetEmployees
        Dim employees As New List(Of Employee)()
        ' Connect to SQL DB and populate list of employee DTO objects
        Return employees
    End Function
End Interface

Затем вы можете сделать аналогичные классы под названиемAccessEmployeeDataAccess а такжеOracleEmployeeDataAccess которые также реализуют интерфейс IEmployeeDataAccess. Затем, также на уровне доступа к данным, я бы создал фабричный класс для каждого поддерживаемого поставщика БД. Я хотел бы заставить все фабрики DataAccess реализовывать один и тот же интерфейс, например так:

Public Interface IDataAccessFactory
    Function NewEmployeeDataAccess() As IEmployeeDataAccess
End Interface

Public Class SqlDataAccessFactory
    Implements IDataAccessFactory

    Public Function NewEmployeeDataAccess() As IEmployeeDataAccess
        Return New SqlEmployeeDataAccess()
    End Function
End Class

Затем в своем бизнес-классе я мог бы сделать что-то вроде этого:

Public Class EmployeeBusiness
    Public Sub New(employeeDataAccess As IEmployeeDataAcess)
        _employeeDataAccess = employeeDataAccess
    End Sub

    Private _employeeDataAccess As IEmployeeDataAcess

    Public Function GetEmployee(id As Guid) As Employee
        Return _employeeDataAccess.GetEmployee(id)
    End Function
End Class

И затем на своей фабрике я бы сделал что-то вроде этого:

Public Class BusinessFactory
    Public Sub New()
        Select Case dataAccessType
            Case "SQL"
                _dataAccessFactory = New SqlDataAccessFactory()
            Case "Oracle"
                _dataAccessFactory = New OracleDataAccessFactory()
            Case "Access"
                _dataAccessFactory = New AccessDataAccessFactory()
        End Select
    End Sub

    _dataAccessFactory As IDataAccessFactory

    Public Function NewEmployeeBusiness() As IEmployeeBusiness
        Return New EmployeeBusiness(_dataAccessFactory.NewEmployeeDataAccess())
    End Function
End Class

Это можно значительно упростить, имея единый набор объектов доступа к данным, которые работают с любым поставщиком базы данных. Для этого вам нужно использовать только базовые типы ADO, такие как IDbConnection вместо SqlConnection и IDbCommand вместо SqlCommand. Тогда ваши объекты доступа к данным могут запросить фабрику провайдера БД, которая может создать новое соединение и т. Д., Когда это необходимо классу DataAccess. Это, однако, легче сделать, когда вы просто вызываете хранимые процедуры или что-то в этом роде. Зачастую, особенно когда вы динамически строите свои предложения SQL в коде, между поставщиками слишком много различий, поэтому вы не можете просто использовать один и тот же класс DataAccess для всех поставщиков БД.

Но это только я ...

Во-первых, я часто вижу, что программисты хотят создать справку по базе данных с помощью методов, похожих на эту форму:

DataTable GetData(string sql)

Важным моментом здесь является то, что метод принимает строку SQL без предоставления параметров запроса. Этоwrong, Этоanti-patternпотому что это побуждает вас (в значительной степени заставляет вас) кодировать sqldata как часть запросаcode, Выmust предоставить некоторый механизм для правильной передачи параметров запроса в виде отдельных данных. Массивы являются обычными, но это не единственный способ. Я также обычно даже не предоставляю перегрузку, которая принимает только строку, поскольку это неизбежно приводит к злоупотреблению. Если вы хотите отправить запрос без параметров, то передайте пустой массив. Таким образом, становится ясно, что это именно то, что вы намереваетесь, и любой, кто использует вашу вспомогательную базу данных, будет поощряться к тому, чтобы научиться правильно использовать параметры.

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

Ваш ответ на вопрос