为什么在DAL中使用Microsoft Sql Server管理对象(SMO)需要在引用DAL的项目中引用SMO dll

本文关键字:引用 SMO DAL 项目 dll 管理 Microsoft Sql Server 对象 为什么 | 更新日期: 2023-09-27 18:21:21

我在谷歌上搜索了一个答案,使用:

"类型'Microsoft.SqlServer.Management.Smo.Server'是在未引用的程序集中定义的。"

为什么在DAL中使用Microsoft Sql Server管理对象(SMO)需要引用项目中的SMO dll?

在引用项目中使用sql-smo

分层解决方案中的sql-smo

sql-smo参考要求

可能还有其他一些人,他们还没有找到这个问题的解决方案或解释。

诚然,我只是一个熟练的谷歌用户,所以如果有人想给我权力级别,并为现有资源指明方向,我会很乐意从那里开始探索。

这是我的设置:

我有一个分层的解决方案:DAL、业务逻辑、服务、UI。有一个托管服务的主机项目。实际上,我正在使用VS2010扩展layerguidance.codeplex.com来设置所有这些项目,这非常好。我使用的是SQL Server 2008 Express和SMO v10。所有解决方案项目都使用"项目引用"进行引用。所有项目都编译到一个通用的顶级Bin文件夹中。

现在的问题是:

在DAL中的类中,我有一个SmoTasks类,它处理与SMO对象的接口,还有一个Utilities类,它从SmoTasks中抽象出来,并提供对其功能的访问,而不需要任何SMO对象作为参数,因此引用项目(读作:业务逻辑层)可以使用非SMO类型进行接口。DAL中一切都很好,它编译得很好,方法通过了测试——它在我的世界中的地位感觉很好。然后在BLL中,我有一个组件,它处理使用Utilities类为将通过服务公开的应用程序执行数据库配置的问题。BLL使用DAL的项目参考,并按预期查看DAL类(la intellisense)。当我编译时,我得到:

类型"Microsoft.SqlServer.Management.Smo.Server"是在未引用的程序集中定义的。必须添加对程序集"Microsoft.SqlServer.Smo,Version=10.0.0,Culture=neutral,PublicKeyToken=88945dcd8080cc91"的引用

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对象不会引起抱怨。我的问题是,为什么?更具体地说:当DAL中的Utilities类已经抽象掉SMO类型时,为什么BLL需要引用SMO

我想要的是DAL(duh)中所有与数据库相关的内容,以及BLL(double-duh)中唯一的业务逻辑有没有其他方法可以使用我忽略的SMO来实现这一点

感谢您宝贵的时间和回答,我谦卑地等待您的回复

编辑:我已经根据Chris的建议调整了我的解决方案,验证了我使用的是项目引用(我是),在手动浏览和添加之前,我使用Muse.VS扩展读取了DAL中对SMO的引用以添加GAC引用,然后我继续为这些程序集设置Copy Local=True,以确保它们在附近。。。但我仍然被这个烦人的编译错误所困扰。

为什么在DAL中使用Microsoft Sql Server管理对象(SMO)需要在引用DAL的项目中引用SMO dll

我认为这可以归结为解决方案中引用事物的方式。所以我要进行一些猜测。

听起来你的DLL引用DAL是一个程序集,而不是一个项目引用。

在编译期间,VisualStudio将其认为必要的所有内容复制到项目BIN目录中。如果您引用一个外部DLL(DAL),则它将仅将该DLL复制到BLL的BIN目录中。

您需要做的是让它也复制SMO程序集,或者通过GAC提供这些SMO程序集中。就我个人而言,我不喜欢GAC'ing的东西,所以我会忽略这一点。

有三种方法可以做到这一点。最简单的方法是简单地将对其他程序集的引用添加到BLL中。显然这不是你想要的。

第二种方法是将DAL项目引用为项目引用。这将允许Visual Studio检测额外的依赖项并相应地复制它们。这也不是你想要的。

第三种方法是将它们作为构建步骤的一部分进行复制。右键单击您的BLL项目,然后转到构建事件。在预构建事件命令行中,输入将必要的SMO文件复制到BLL项目BIN目录的命令。

对于主服务项目,您也必须再次执行此操作。

用道歉来回答你自己的问题是令人沮丧的,"我是个白痴"。。。但是,我是个白痴:

Utilities中,违规方法存在重载,确实包含Smo.Server参数。我删除了那个重载(重构前测试中的工件),瞧,问题解决了/愚蠢得到了证实!我在这里学到的有趣的一点是,使用Utilities类的其他方法是完全可以的,这些方法没有包含Smo对象的重载,这意味着即使Utilities类中的函数需要一个Smo对象作为参数,只要我没有调用该方法或其重载之一,引用也会顺利解决。我的新问题是,为什么?如果我从依赖链中较高的项目调用该函数的另一个版本,为什么重载的存在对引用解析很重要?是否存在一些内部循环,它会遍历函数的所有版本,检查是否调用了任何版本的引用。。。