错误: 未找到与不变名称为'System.Data.SqlClient'的ADO.NET提供程序相对应的Entity Framework提供程序。

49

我最近将一个老项目的Entity Framework版本从4或5更新到了版本6。现在我遇到了这个异常:

发生了类型为 'System.InvalidOperationException' 的异常,但未在用户代码中处理,位于 EntityFramework.dll 中。

额外信息:找不到与不变名称为'System.Data.SqlClient'的 ADO.NET 提供程序对应的Entity Framework提供程序。确保该提供程序已在应用程序配置文件的 'entityFramework' 部分中注册。请参见http://go.microsoft.com/fwlink/?LinkId=260882 获取更多信息。

我在Google上搜了这个错误,并浏览了一些SO讨论串,但是其中没有一个可以解决我的问题。这是我的App.config文件的内容:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <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>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>
</configuration>

我已经从我的项目中卸载了Entity Framework并重新安装了它,删除了所有旧EF文件的引用并重新安装了它,但对我来说什么都不起作用。 我一直收到这个错误。


你考虑过降级吗?还是你正在努力让那个版本正常工作? - meda
EF6有一些对我的项目非常有用的功能。 - Leon Cullens
你用的是哪个版本的 Visual Studio?因为我知道 2010 版本在使用较新的 EF(Entity Framework)时有些问题,我自己遇到过一个问题,可以参考这里 - meda
Visual Studio 2013 高级版。 - Leon Cullens
13个回答

51

我曾遇到这样一个问题:我有一个模型项目,它引用了EntityFramework和.SqlServer程序集,还有一个使用ASP.NET MVC的单独UI项目。我想将EF版本从4.1升级到6.1。

实际上,我需要执行此处所描述内容的部分http://robsneuron.blogspot.com/2013/11/entity-framework-upgrade-to-6.html。我想强调的是,我没有将这些项目添加到我的UI项目中,也没有将配置添加到UI项目的web.config文件中,因为这些步骤会违反我的关注点分离原则。

我所做的是在我的模型项目中,我需要将EntityFramework.SqlServer(以及EntityFramework参考)的“Copy Local”引用设置翻转为“False”,并保存所有更改,以便让项目将<Private>节点放入.csproj文件中,然后再将其设置回“True”并再次保存,以便True最终成为最终值。

我还必须在我的DbContext派生类的构造函数中添加hack行,以强制使用程序集,即使该行不起作用。这两个步骤都是我从博客文章中学到的。

public MyContext : DbContext
{
    public MyContext() : base("name=MyContext")
    {
        // the terrible hack
        var ensureDLLIsCopied = 
                System.Data.Entity.SqlServer.SqlProviderServices.Instance;   
    }

我希望向我所引用博客的作者,以及所有在SO上提问和回答问题的人表示感谢,他们尝试帮助我们克服这个可怕的 bug。


4
如果可以的话,我会给你点赞两次。将实体框架的引用和配置部分从 UI 项目中分离出来,这正是我所期望的。谢谢! - BCA
2
2017年10月。我们已经成功登陆火星,发明了伟哥,并且能够用手机捕捉口袋妖怪。然而,我们最聪明的科学家仍无法自动解决复制DLL的问题。感谢@bcr的帮助 :) - Dima
2
2019年1月,这仍然是一个美好的修复。感谢您发布此内容。 - Bob Black
谢谢您。我意识到我来晚了,但这解决了我的问题。 - ChettDM

36

好的,这很奇怪。我有几个项目:一个是UI项目(一个ASP.NET MVC项目),其他的是一些用来存储数据的项目。存储数据的项目引用了EF,但UI项目没有(因为它不需要,它只需要引用其他项目)。在我也为UI项目安装了EF之后,一切都开始正常工作了。这就是为什么它会将这段代码添加到我的Web.config文件中:

<entityFramework>
  <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
  <providers>
    <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
  </providers>
</entityFramework>

5
不奇怪,你的dlls的app.configs没有被嵌入到dll中,因此如果你需要配置文件,你需要将其添加到主应用程序/ web.config中。不要忘记,这也适用于连接字符串。 - SynerCoder
我有同样的问题,但是没有解决方案 :( - Neo
谢谢,这也解决了我的问题。虽然我们正在通过存储库模式使用SOC,但EF仍然需要在Web项目中引用... - Rob
这指引我朝着正确的方向前进,但对我来说另一个遗漏的部分是在我的项目中手动添加对 EntityFramework.SqlServer 的引用。在EF6中,当你不使用NuGet来配置时,需要所有这些内容,请参阅MSDN文档了解更多信息。 - Paul
这也解决了我的问题,但不确定它是否是正确的方法。无论如何,感谢修复 :) - Bhuwan Maharjan

16

我有同样的问题,不同之处在于我没有访问源代码的权限。我通过将正确版本的 EntityFramework.SqlServer.dll 放置在应用程序的 bin 目录中来解决了我的问题。


13

我已经解决了。您需要在解决方案中重新安装Entity Framework。请遵循以下任一方法。

第一种方法 = 在您的解决方案或项目中右键单击,然后单击管理NuGet软件包。选择'EntityFramework',选择适当的项目,然后单击“确定”。

或者

第二种方法 = 转到控制台包管理器并运行Install-Package EntityFramework

希望对您有所帮助。


右键单击解决方案根目录并管理Nuget包。easy.WIN。我添加了一个项目,但它在新项目中丢失了,这很自然。 - CAD bloke
我明白你的意思,而且也是正确的。如果你愿意,可以改进我的答案。谢谢 :) - Sandy

6
亨德里的回答是100%正确的。我在我的应用程序中也遇到了同样的问题,其中有一个处理数据库的存储库项目,使用封装EF db上下文操作的方法。其他项目使用这个存储库,我不想在这些项目中引用EF。但是,不知何故,我觉得这不是合适的,我只需要在存储库项目中使用EF。 无论如何,将EntityFramework.SqlServer.dll复制到其他项目输出目录可以解决问题。为了避免问题,当你忘记复制这个dll时,你可以更改存储库构建目录。转到存储库项目的属性,选择“生成”选项卡,在输出部分中,你可以将输出目录设置为其他项目的构建目录。 当然,这只是一种解决方法。也许在某些地方提到的黑客技巧更好:
var instance = System.Data.Entity.SqlServer.SqlProviderServices.Instance;

尽管如此,对于开发目的来说已经足够了。稍后在准备安装或发布时,您可以将此文件添加到包中。

我对EF还很陌生。有没有更好的方法来解决这个问题?我不喜欢“hack”——它让我觉得有一些“不安全”的东西。


6
我已经在我的DBContext中使用以下代码解决了问题:
 
public partial class Q4Sandbox : DbContext
    {
        public Q4Sandbox()
            : base("name=Q4Sandbox")
        {
        }
public virtual DbSet Employees { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder) { var instance = System.Data.Entity.SqlServer.SqlProviderServices.Instance; } }
感谢SO成员的帮助。

等等,你提供的代码根本没有修复原帖中的错误?你甚至没有使用“instance”。 - Leon Cullens
1
Leon,我正在使用实例! - Aji
你试过源代码了吗?你遇到这个问题了吗?我曾经遇到过这个问题并解决了它。另外,关于你的问题,请检查我所写的代码是否是由微软建议的。 - Aji
1
我只是按照这里所示,在我的DBContext类中添加了这行代码(var instance = System....),而没有修改app.config或将dll复制到构建文件夹中,它就可以工作了。对于VB程序员:“Dim instance = System.Data.Entity.SqlServer.SqlProviderServices.Instance”。非常感谢。 - Michael Bayer
1
谢谢您,先生。这也是我代码中缺失的部分。看起来它无法从App.config文件中获取实例 :) :) - Ange1
显示剩余2条评论

3
将"EntityFramework.SqlServer.dll"添加到您的bin文件夹中。问题将得到解决。

2
尝试添加以下运行时程序集绑定:
<runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="EntityFramework" publicKeyToken="b77a5c561934e089" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>

嗯,感谢您的回答,我发现了一些问题。我的ASP.NET项目仍然引用了EF,但它是针对EF5的。我将其更改为EF6,但不幸的是这并没有解决问题。 - Leon Cullens

2
在每个项目中安装Entity Framework(例如,在Web中,在类库中)从NuGet包管理器,否则打开工具 - Nuget包管理器 - 包管理器控制台并使用Install-Package EntityFramework来安装Entity Framework。
不需要在每个配置文件中添加以下代码。默认情况下,它将被添加到通过Entity Framework调用数据库的项目中。 <entityFramework> <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" /> <providers> <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /> </providers> </entityFramework>

2

我曾经遇到过同样的问题,唯一有效的解决方法是使用Uninstall-Package从每个项目中卸载实体框架包。然后在整个解决方案中重新安装它。它会要求你选择要在哪个项目中安装它,你应该选择全部。


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