Почему для использования объектов управления сервером Microsoft Sql (SMO) в DAL требуются ссылки на библиотеки DLL SMO в проекте, который ссылается на DAL?

Я искал ответ в Google, используя:

«Тип Microsoft.SqlServer.Management.Smo.Server определен в сборке, на которую нет ссылок».

Почему для использования объектов управления сервером Microsoft Sql (SMO) в DAL требуются ссылки на библиотеки DLL SMO в проекте, на который ссылаются?

использование sql smo в упомянутых проектах

SQL SMO в многоуровневых решениях

Требования к справочнику по sql smo

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

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

Вот мои настройки:

У меня многоуровневое решение: DAL, Business Logic, Services, UI. Есть проект hosts, в котором размещаются сервисы. На самом деле я использую расширение VS2010 layerguidance.codeplex.com, что очень удобно для настройки всех этих проектов. . Я использую SQL Server 2008 Express и SMO ​​v 10. На все проекты решений ссылаются с помощью ссылок на проекты. Все проекты компилируются в общую папку Bin верхнего уровня.

Теперь проблема:

Среди классов в DAL у меня есть класс SmoTasks, который обрабатывает взаимодействие с объектами SMO, и класс Utilities, который абстрагируется от SmoTasks и предоставляет доступ к его функциям, не требуя каких-либо объектов SMO для параметров, поэтому ссылки на проекты (читай: уровень бизнес-логики) может взаимодействовать с использованием типов, отличных от SMO. В DAL все хорошо, компилируется нормально, методы проходят проверку - он чувствует себя хорошо на своем месте в моем мире. Затем в BLL у меня есть компонент, который использует класс Utilities для выполнения конфигурации базы данных для приложения, которое будет отображаться через службы. BLL использует ссылку проекта на DAL и видит классы DAL (а-ля intellisense), как и ожидалось. Однако, когда я компилирую, я получаю:

Тип Microsoft.SqlServer.Management.Smo.Server определен в сборке, на которую нет ссылок. Вы должны добавить ссылку на сборку «Microsoft.SqlServer.Smo, Version=10.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91».

Код в BLL выглядит так:

 public bool CreateTables(string connectionString)
    {

        bool result = default(bool);


        // Data access component declarations.
        Utilities utilities = new Utilities();

        // Step 1 - Calling CreateTables on Utilities.
        result = utilities.CreateTables(connectionString);

        return result;

    }

Строка, на которую указывает ошибка:

result = utilities.CreateTables(connectionString);

Я мог бы, конечно, добавить ссылки SMO ​​в BLL, и тогда BLL был бы счастлив, но это нарушает мою цель разработки слабосвязанных проектов. Если я добавляю сборки SMO ​​в BLL, он компилируется, а затем обращение к объектам BLL на уровне сервисов не вызывает жалоб. Мой вопрос, почему? Более конкретно: Зачем BLL нужны ссылки на SMO, когда класс Utilities в DAL уже абстрагируется от типов SMO?

Я хочу, чтобы вся база данных, связанная с базой данных, жила в DAL (дух) и только бизнес-логика в BLL (двойной дух). Есть ли другой способ добиться этого с помощью SMO, который я упустил из виду?

Спасибо за ваше ценное время и ответы, я смиренно жду ваших ответов

Изменить: я скорректировал свое решение на основе предложений Криса, проверил, что я использую ссылки на проект (я), прочитал ссылки на SMO в DAL, используя Muse.VSExtensions, чтобы добавить ссылку GAC, прежде чем я просматривал и добавляя вручную, затем я пошел дальше и установил Copy Local = True для этих сборок, чтобы быть вдвойне уверенным, что они рядом... но я все еще застрял с этой раздражающей ошибкой компиляции.


person Erikest    schedule 25.01.2012    source источник
comment
Как ни странно, комментирование оскорбительной строки позволяет выполнить компиляцию. В Utilities есть и другие функции, которые выглядят идентично этой, за исключением того, что они вызывают другой метод. Все методы Utilities выглядят примерно одинаково, просто переходя к SmoTasks...   -  person Erikest    schedule 26.01.2012


Ответы (2)


Я думаю, что это сводится к тому, как вещи упоминаются в вашем решении. Итак, я собираюсь сделать пару предположений.

Похоже, ваша DLL ссылается на DAL как на сборку, а не как ссылку на проект.

Во время компиляции Visual Studio копирует все, что считает необходимым, в каталог BIN проекта. Если вы ссылаетесь на внешнюю DLL (DAL), она скопирует эту DLL только в каталог BIN вашего BLL.

Что вам нужно сделать, так это заставить его также копировать сборки SMO ​​ИЛИ сделать эти сборки SMO ​​доступными через GAC. Лично мне не нравятся вещи GAC, поэтому я проигнорирую это.

Есть три способа сделать это. Проще всего просто добавить ссылку на эти другие сборки в ваш BLL. Очевидно, это не то, что вы хотите.

Второй способ — указать проект DAL как ссылку на проект. Это позволит Visual Studio обнаруживать дополнительные зависимости и соответствующим образом копировать их. Это тоже не совсем то, что вы хотите.

Третий способ — скопировать их как часть шага сборки. Щелкните правой кнопкой мыши проект BLL и перейдите в раздел «Сборка событий». В командной строке события перед сборкой введите команды для копирования необходимых файлов SMO в каталог BIN проектов BLL.

Вам придется сделать это снова для основного проекта службы.

person NotMe    schedule 25.01.2012
comment
Технически существует четвертый способ. Вручную скопируйте сборки SMO ​​в каталог BIN BAL. Однако вполне возможно, что эти файлы будут удалены, и вы вернетесь к тому, с чего начали. - person NotMe; 26.01.2012
comment
В этом случае я использую все ссылки проекта для ссылки на BLL, DAL, сервисный уровень и т. д. Может быть, вы можете объяснить, почему это не то, что я хочу (и я бы приветствовал здесь больше понимания), но если это так, ссылки должно работать, да? - person Erikest; 26.01.2012
comment
Черт, я думал, что вы меня направили в правильном направлении, потому что я проверил, что свойство Copy Local, если ссылка на сборку была установлена ​​​​на true, и, как ни странно, это не так (как сборки в GAC, за исключением того, что они были добавлены путем просмотра их папку, так как они не появились в списке GAC). Я его поменял и сборки появляются в папке bin, но ошибка остается. Я просмотрел obj/ResolveAssemblyCache.cache для BLL и вижу там сборки smo и их пути, но, увы, те же ошибки компиляции. - person Erikest; 26.01.2012

Депрессивно отвечать на свой вопрос с моей виной: «Я идиот»… но, ну, я идиот:

В Utilities была перегрузка метода-нарушителя, который действительно содержал параметр Smo.Server. Я убрал эту перегрузку (артефакт от тестирования перед рефакторингом) и вуаля, проблема решена/идиотизм подтвержден! Интересная вещь, которую я здесь узнал, заключается в том, что использование других методов класса Utilities, у которых не было перегрузок, содержащих объекты Smo, было абсолютно правильным, то есть даже с функцией в классе Utilities, которая требовала объект Smo для параметра, до тех пор, пока поскольку я не вызывал этот метод или одну из его перегрузок, ссылки разрешались без заминок. У меня новый вопрос: почему? Почему существование этой перегрузки имеет значение для разрешения ссылки, если я вызываю другую версию этой функции из проекта, расположенного выше в цепочке зависимостей? Есть ли какой-то внутренний цикл, в котором он проходит по всем версиям ссылок на проверку функций, если какая-либо версия была вызвана...

person Erikest    schedule 30.01.2012