找不到适用于具有不变名称“System.Data.SqlClient”的 ADO.NET 提供程序的 Entity Framework 提供程序。

600

在通过NuGet下载EF6并尝试运行我的项目后,返回以下错误:

未找到与不变名称'System.Data.SqlClient'对应的ADO.NET提供程序的Entity Framework提供程序。 确保该提供程序已在应用程序配置文件的“entityFramework”部分中注册。欲知详情,请参见http://go.microsoft.com/fwlink/?LinkId=260882

enter image description here


我使用EF5,没有使用“providers”和“provider”等内容,所以考虑将其删除? - ta.speot.is
1
请在此处放置您的连接字符串的副本。 - pylover
连接字符串在图片中(App.config), 顺便说一下,非常简单,我调用构造函数 public BaseStorage(): base ("RaptorDB") {},BaseStorage() 继承自 EF5 中的 DbContext,在 EF5 中一切都运行得很完美,但在 EF6 中就不行了。 - Fernando Vellozo
12
通过安装EF6,第二个项目(控制台)的问题将会得到解决,感谢所有以任何方式提供帮助的人! - Fernando Vellozo
4
对我来说,这似乎是由于Visual Studio没有意识到EntityFramework.SqlServer程序集实际上被基础项目使用所致。如果您像@Carra的答案那样做(https://dev59.com/CGMl5IYBdhLWcg3wXWET#23059931),则不必将EF添加到引用基础项目的每个项目中-更加简洁。 - tehDorf
35个回答

673

我遇到了同样的问题,看起来虽然通过NuGet包管理器安装了EntityFramework,但它没有正确安装到项目中。

我成功地通过在Package Manager Console上运行以下命令来解决了这个问题:

PM> Install-Package EntityFramework

37
PMC写道,“'EntityFramework 6.0.1'已安装”,但我将其添加到我的控制台应用程序中(实际上没有使用EF),但这也对我有帮助。如果我从控制台应用程序的引用中删除EF,错误就会返回,我不明白为什么 - 我的控制台应用程序正在使用存储库项目(该项目使用EF)。谢谢帮忙! - Prokurors
35
如果你的解决方案中有多个项目,请不要忘记在命令行中添加-ProjectName <ProjectName> ...!!! - Eugenio Miró
1
使用 -Pre 选项告诉 NuGet 安装预发布包。我不建议使用它。我遇到了类似的错误,但解决方案是在主项目(Web/控制台/或其他)中安装 EntityFramework,而不是在类库中安装。 - Davide Icardi
13
我也遇到了同样的问题。我的项目没有引用 EF,但是 EF 的 dll 文件在 Debug 文件夹中。对该项目运行下述命令后,EntityFramework.SqlServer.dll 被添加到了 Debug 文件夹中,问题得以解决。 - qujck
6
直到我将项目部署到测试服务器上,才出现了这个错误。确实是缺少EntityFramework.SqlServer.dll,通过包管理器安装EF后问题得到解决。这样可以向项目添加两个相关引用,并在web.config中添加entityFramework设置。我猜本地的IIS能够在本地源代码编译程序集,但是由于权限问题,Web服务器上的完整IIS无法实现这一点。 - Atters
显示剩余9条评论

411

您已将EF添加到类库项目中。 您还需要将其添加到引用它的项目(控制台应用程序,网站或其他项目)中。


270
这个回答绝对荒谬。我为什么需要那样做呢?更荒谬的是,它居然奏效了。 - Robert
19
你不需要在控制台应用程序中安装EF,可以参考下面的答案。 - Francisco Goldenstein
8
你的答案是正确的。只需将 EntityFramework.SqlServer.dll 引用到使用 EF 库的前端项目中,就可以解决问题。因此不要使用这个 EF(只使用 DLL)。 - Sith2021
32
在控制台/ Web 应用程序中,您不必添加对 EF 的引用。 您只需要确保将 EntityFramework.SqlServer.dll 复制到 bin 目录即可。 如果添加强引用可能会破坏架构(如果您构建了多个层次,则顶层执行程序集甚至不应知道 EF 的存在)。 可以确保 SQL Server 提供程序已复制。 例如,请参见 https://dev59.com/f2Yr5IYBdhLWcg3wAFg0#19130718 - ken2k
4
我猜测 EntityFramework.SqlServer.dll 没有被检测出来作为一个依赖项的原因是因为 Entity Framework 动态加载它。当配置文件中唯一的引用是 SQL 提供程序时,你的项目该如何知道复制它呢?请问你需要什么帮助吗? - Joel McBeth
显示剩余4条评论

223

在您的控制台应用程序中不需要安装Entity Framework,只需添加对EntityFramework.SqlServer.dll程序集的引用即可。您可以从使用Entity Framework的Class Library项目中复制此程序集到LIB文件夹并添加对它的引用。

总之:

  • 类库应用程序:
    • 安装Entity Framework
    • 编写数据层代码
    • app.config文件包含与Entity Framework相关的所有配置,但不包括连接字符串。
  • 创建控制台、Web或桌面应用程序:
    • 添加对第一个项目的引用。
    • 添加对EntityFramework.SqlServer.dll的引用。
    • app.config/web.config包含连接字符串(记住配置项名称必须与DbContext类的名称相同)。

20
正确的答案。无需安装EF。EntityFramework.SqlServer.dll。 - Tom Stickel
15
我必须同意。这完全是正确的答案。引用一个大小为1/2 MB的dll或拉取大于5.5 MB的EF NuGet项目。这稍微降低了多层架构的价值。微软的表现很糟糕:我有4个层次,我的顶层应该真的没有理由了解EF的任何内容。 - 72GM
20
还是很荒谬。例如,为什么前端需要引用SqlServer?在我的情况下,前端根本不关心。但它确实有效。+1 - Mike de Klerk
2
这很有帮助。非常感谢。 - peter_the_oak
2
这难道不会使得更新 EntityFramework 的版本变得困难吗?你必须记得去更新对 DLL 的引用。 - crush
显示剩余5条评论

116

如果您忘记包含“EntityFramework.SqlServer.dll”,也会看到此消息。

这似乎是EF6中新添加的文件。最初我没有将其包含在我的合并模块中,遇到了此处列出的问题。


7
在之前的一个项目(a)中,我遇到了这个问题,它引用了一个引用了EF的项目(b)。在清理和删除项目(a)的bin文件夹后,重新构建,EF的引用被识别了,但EF.SqlServer.dll没有。将其手动复制进去对我起了作用。 - dan richardson
2
@dan richardson感谢您提到“删除bin文件夹”。 - Rajshekar Reddy
在 EF6 升级后,在尝试运行 LINQPad 脚本时我遇到了错误。即使在 LINQPad 中引用了 EntityFramework.SqlServer.dll,也无法解决它,直到我在 VS2013 中重建了我的解决方案。然后新的引用在 LINQPad 中才能正确解析,并且我的脚本成功运行! - Chris
在我的情况下,我在开发环境中没问题,但是当我发布时出现了引用问题。通过比较开发环境中的库列表和服务器上的 bin 文件夹,我注意到缺少 EntityFramework.SqlServer.dll,我只需要上传它并刷新应用程序,问题就解决了。 - Henry Rodriguez
这就是我的问题,谢谢!请查看@Anders的简洁解决方案,以避免忘记在每个所需项目中包含DLL而出现问题。 - SharpC

61

不需要将 EntityFramework.SqlServer 添加到托管项目中,您可以通过以下方式确保在模型/实体项目中静态引用它

static MyContext()
{
    var type = typeof(System.Data.Entity.SqlServer.SqlProviderServices);
    if(type == null)
        throw new Exception("Do not remove, ensures static reference to System.Data.Entity.SqlServer");
}

这将使构建过程将汇编文件与宿主项目一起包含。

更多信息请查看我的博客http://andersmalmgren.com/2014/08/20/implicit-dependencies-and-copy-local-fails-to-copy/


5
我认为这是一个很好的干净的解决方案,我们不需要在应该持久性无关的项目中包含与持久性相关的DLL引用。 - JTech
3
同意,这适用于任何具有隐式依赖项的库,而不仅限于持久化库。 - Anders
3
当您在程序集中对某个类型具有明确的依赖关系时,该类型将被构建过程复制。然而,在这种情况下,您没有明确的依赖关系,因此构建过程将无法将程序集复制到构建文件夹中。我的代码只是确保存在对该程序集中任何类型的明确引用。 - Anders
2
没有明确的依赖关系,您的代码就不会与程序集相关联,也不会被复制到输出目录中。 - Anders
2
这太棒了。 - Kris
显示剩余11条评论

50

当您通过Nuget安装Entity Framework 6时,有时会错过另一个可执行文件EntityFramework.SqlServer。只需将Nuget包添加到该项目即可。

有时对于测试项目上述方法不起作用

要解决测试项目中的这个问题,只需将此方法放置在测试项目中:

public void FixEfProviderServicesProblem()
{
    var instance = System.Data.Entity.SqlServer.SqlProviderServices.Instance;
}

这个方法从未被调用,但根据我的观察,编译器会移除所有“不必要”的程序集,若不使用 EntityFramework.SqlServer 的东西,测试就会失败。


3
这不太美观,但它解决了我在测试项目中遇到的问题。其他的解决方案都没有奏效。 - Honorable Chow
在我的情况下,只需在“管理解决方案的Nuget包”中将Entity Framework添加到我的测试项目即可。 - Juha Palomäki
实际上,您需要将其放入任何项目中(不仅仅是测试),以确保在编译后“结果库集”中包含System.Data.Entity.SqlServer(注意:Unity或其他IoC工具可能会更改此规则,您需要从测试项目中调用此代码)。 - Roman Pokrovskij
这实际上是最好的解决方案,因为你不必在项目中到处引用 Entity Framework。 - Daniel Lobo
这指引我朝着正确的方向前进。EntityFramework.SqlServer 已经被添加到你的类库中,但如果没有使用它,它将不会被放置在应用程序的输出文件夹中。我通过添加一个 ExecutionStrategy 来解决了这个问题,我仍然需要这样做,所以在 DbConfiguration 类中添加一行像 SetExecutionStrategy("System.Data.SqlClient", () => new SqlAzureExecutionStrategy()); 的代码就可以解决问题了。 - Jan_V

28

添加此函数

private void FixEfProviderServicesProblem()

在库类中添加数据库上下文类,并将缺失的DLL文件EntityFramework.SqlServer.dll复制到正确的位置。

namespace a.b.c
{
    using System.Data.Entity;

    public partial class WorkflowDBContext : DbContext
    {
        public WorkflowDBContext()
            : base("name=WorkflowDBConnStr")
        {
        }

        public virtual DbSet<WorkflowDefinition> WorkflowDefinitions { get; set; }
        public virtual DbSet<WorkflowInstance> WorkflowInstances { get; set; }
        public virtual DbSet<EngineAlert> EngineAlerts { get; set; }
        public virtual DbSet<AsyncWaitItem> AsyncWaitItems { get; set; }
        public virtual DbSet<TaskItem> TaskItems { get; set; }
        public virtual DbSet<TaskItemLink> TaskItemLinks { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
        }

        private void FixEfProviderServicesProblem()
        {
            // The Entity Framework provider type 'System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer'
            // for the 'System.Data.SqlClient' ADO.NET provider could not be loaded. 
            // Make sure the provider assembly is available to the running application. 
            // See http://go.microsoft.com/fwlink/?LinkId=260882 for more information.
            var instance = System.Data.Entity.SqlServer.SqlProviderServices.Instance;
        }
    }
}

.


抱歉,我试图撤销它...因为我认为它不会起作用...但它确实起作用了!它说除非答案被编辑,否则我无法更改我的投票,因为时间太长并且已被锁定... - Seabizkit
这对我也起作用了。我们有一个使用EF 6的库项目和一个使用该库的控制台应用程序。我们遇到了与OP相同的异常。我们不希望在应用程序配置文件中放置EntityFramework特定的配置,因此这种方法适用于我们。谢谢。 - Rob
1
你在哪里调用 FixEfProviderServicesProblem?我尝试在构造函数中调用,但没有成功。 - Francis Ducharme
1
我从不调用它 - 也不必这样做。事实上,它的存在让 .net 认为它是必需的,并将 EntityFramwork 包含为依赖项。 - Johannes
可能是从 https://dev59.com/f2Yr5IYBdhLWcg3wAFg0#19130718 转载来的?不过无论如何,因为清晰地阐述了在哪里以及如何使用它,所以点赞。 - David

22

这些方法都对我没用。我在另一个stackoverflow问题中找到了解决方案。为了方便参考,我会在这里添加:

你需要创建一个引用,这样它将被复制到应用程序路径中。因为它稍后将在运行时被引用。所以你不需要复制任何文件。

private volatile Type _dependency;

public MyClass()
{
    _dependency = typeof(System.Data.Entity.SqlServer.SqlProviderServices);
}

2
不需要添加引用其他可能引用此程序集的项目。 - tehDorf

9
新创项目引用使用Entity Framework的项目,需要在其bin文件夹中添加以下两个程序集:
  • EntityFramework.dll
  • EntityFramework.SqlServer.dll
向启动项目的.config文件的<configSections>添加<section>,可以使第一个程序集在该bin目录中可用。您可以从Entity Framework项目的.config文件中复制此内容:
<configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>

为了使第二个.dll在bin文件夹中可用,虽然不实用,但可以从Entity Framework项目的bin文件夹手动复制。 更好的选择是在Entity Framework项目的Post-Build事件中添加以下行,将自动化该过程:

cd $(ProjectDir)
xcopy /y bin\Debug\EntityFramework.SqlServer.dll ..\{PATH_TO_THE_PROJECT_THAT_NEEDS_THE_DLL}\bin\Debug\

4
谢谢,我在数据层中使用了Entity Framework使其独立,但不幸的是微软不允许我们真正隔离数据层,并迫使我们将数据库技术强加于用户体验。我原本希望不必这样做。 - Matt

8

当测试项目出现错误时,最好的解决方法是用以下方式对测试类进行装饰:

[DeploymentItem("EntityFramework.SqlServer.dll")]

确实很漂亮,但会增加更多的工作量,而且更容易被遗忘。通过“强制引用”技巧,您只需要在真正需要使用EF的项目上执行它。 - Charles Roberto Canato

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接