实体框架无法更新数据库

本文关键字:更新 数据库 框架 实体 | 更新日期: 2023-09-27 18:26:18

每当我保存到DB时,我的应用程序都会崩溃,并出现以下错误。

在DLL"SqlServerSpatial110.DLL"中找不到名为"SetClrFeatureSwitchMap"的入口点。

这个错误是在昨天下午Windows更新和电脑重新启动后出现的。该dll未在项目中引用,也不在bin文件夹中。

我使用EF5,可以连接到数据库并提取数据,但当我调用ObjectContext.SaveChanges()时,会发生错误。

该应用程序不使用几何图形,所以我不知道这是从哪里来的。

实体框架无法更新数据库

我遇到了同样的问题,并通过在我的应用程序的web.config中添加以下行来修复它:

<runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <dependentAssembly>
      <assemblyIdentity name="Microsoft.SqlServer.Types" publicKeyToken="89845dcd8080cc91" />
      <bindingRedirect oldVersion="1.0.0.0-11.0.0.0" newVersion="10.0.0.0" />
    </dependentAssembly>
  </assemblyBinding>
</runtime>

这迫使EntityFramework使用SqlServer.Types.dll的版本10,该版本显然没有Geometry类型。

上面的答案对我不起作用,所以我做了更多的挖掘,并在这里分享我的发现。

摘要:在SQL Server 2012 SP2(11.0.2100.60)和SP3(11.0.6020.0)之间,Microsoft SQL Server System CLR TypesSQLSysCLRTypes.msi)库发生了更改,可以通过将此程序包和任何杂散DLL升级到最新版本(在撰写本文时对应于2012 SP4/111.0.7001.0)来解决此问题。


这个软件包实际上只有两样东西:

  • Microsoft.SqlServer.Types.dll-.NET包装库
  • SqlServerSpatial110.dll-包含空间功能的本地库

请注意,SQLSysCLRTypes.msi有很多版本,与SQL Server的每个主要/次要版本相对应,但令人恼火的是,它们都是用相同的文件名发布的,除非您执行完整的SQL Server安装,否则它们往往是从SQL Server功能包安装东西的手动先决条件(例如,请参阅https://www.microsoft.com/en-us/download/details.aspx?id=56041)

从SQL 2012 SP3版本的包开始,SqlServerSpatial110.dll导出函数SetClrFeatureSwitchMap,该函数是从.NET包装DLL中的某个位置调用的。在SP3之前,该函数似乎不存在,.NET包装器也没有尝试使用它。(您可以使用dumpbin /exports <dll file>列出DLL导出)

如果CLR Types MSI软件包安装在特定的计算机上,并且.NET程序的工作目录中存在这些DLL的其他次要版本,则可能会出现错误。如果您将程序与其依赖库一起分发,以避免最终用户需要额外的安装步骤,则很容易发生这种情况。

无论何时将.NET库安装到系统并包含在全局程序集缓存(GAC)中,系统版本都将始终由.NET程序加载,即使在工作目录中可以找到"本地"副本也是如此。对于本机库,首先使用工作目录副本。这意味着,当您在应用程序中引用Microsoft.SqlServer.Types并且在应用程序目录中具有匹配版本的两个DLL时,如果Microsoft.SqlServer.Types安装在具有相同主版本(即11.0.0.0)的系统上,则当它试图加载其本地库依赖项并且从工作目录中获得CCD_ 10的旧版本而不是从系统上可能安装的任何地方获得正确版本时。

如何修复:确保SqlServerSpatial110.dll的任何副本都具有与Microsoft.SqlServer.Types.dll的任何副本相同的次要版本,并确保每个副本都具有最新版本。这可能只适用于SQL Server 2012,但在最终发布Service Pack的SQL Server的较新版本中也可能出现类似问题。

请注意,将对Microsoft.SqlServer.Types(在Visual Studio中)的引用的"特定版本"设置为"True"不会产生任何效果,因为所有SQL Server 2012 CLR类型库版本都向.NET(11.0.0.0)公开相同的版本号,无论它们来自哪个service pack。

参考文献:

  • 如何强制.NET使用程序集的本地副本';s在GAC中
  • https://learn.microsoft.com/en-us/cpp/build/reference/dumpbin-reference

因此,如果我在应用程序的启动中添加以下代码行,它将使用SQL 2014版本的Microsoft.SqlServer.Types程序集,该程序集似乎没有上述问题。

System.Data.Entity.SqlServer.SqlProviderServices.SqlServerTypesAssemblyName = "Microsoft.SqlServer.Types, Version=12.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91";

这适用于安装了SQL Server 2014 SDK的计算机。

我也在这里提交了一个微软的错误:

https://connect.microsoft.com/SQLServer/Feedback/Details/2139143

我知道我参加聚会迟到了,但我在MSSQL 2012中遇到了同样的问题,这真的很烦人。I无法在具有Spacial列的表中运行任何查询。这有点棘手。我总结了我的方法,以防其他人,

原因是SP3和CLR之间存在一些不一致。最好的方法是检查C:'Windows'assembly,如果你在这里看到一些Microsoft.SqlServer.Types,你需要再次删除并安装它们。去除它们有点棘手:

  1. 可能从windows更新中卸载所有SQL server更新,我只是为Service Pack 1,2,3 做了这件事

  2. 转到此处的注册HKLM'SOFTWARE'Classes'Installer'Assemblies'Global中的此位置

  3. 删除所有名为Microsoft.SqlServer.Types的项,但在此之前请进行注册表备份注意不要弄乱注册表。

  4. 以管理员身份运行Developer Command Prompt并运行此命令gacutil -i Microsoft.SqlServer.Types

  5. 修复您现有的SQL server的原始版本。

最后,我能够在任何表上执行任何查询,即使使用几何(空间)数据

希望这能帮助一些人。

根据我处理此错误的经验,当使用带有SQL Server Service Pack 3的SQL Server时,只有针对.NET 4(而不是.NET 4.5)的实体框架5才会发生这种情况。有关可能的根本原因的更多信息,请点击此处。对我有效的解决方案:
1) KdBoer修复,或
2) 将应用程序更新到Entity Framework 6

我在使用Visual Studio 2022而不是之前的2019时发生了这种情况,尽管我认为这是因为在VS 2022中,默认情况下选中了"对网站和项目使用64位版本的IIS Express"选项(在选项/项目和解决方案/web项目中),而在2019 中

可能是由其间的其他安装引起的,但对我来说,解决方案(或变通方法)是卸载";Microsoft SQL Server System CLR Types for SQL Server 2012";32位和64位版本。碰巧我安装了更多的,所以直到现在我都没有遇到任何问题。在尝试之前,我在这里提供了所有选项(更改web.config等),但都没有用。

@javacow提供的解决方案是这个想法的来源,因为它说:

确保SqlServerSpatial110.dll的任何副本都具有相同的次要副本版本为Microsoft.SqlServer.Types.dll的任何副本,并确保每个都有最新版本。

我试图在两个"修复"的安装程序中匹配运行修复选项的次要版本和主要版本;Microsoft SQL Server System CLR Types for SQL Server 2012";但它没有运行,因为它缺少一些安装包,所以我决定卸载(为了以后安装,我似乎无法安装,因为它抱怨安装了更新的版本)。所以我试着运行,即使没有这个版本,我的程序也能正常运行。