实体框架无法更新数据库
本文关键字:更新 数据库 框架 实体 | 更新日期: 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 Types(SQLSysCLRTypes.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
,你需要再次删除并安装它们。去除它们有点棘手:
-
可能从windows更新中卸载所有SQL server更新,我只是为Service Pack 1,2,3 做了这件事
-
转到此处的注册
HKLM'SOFTWARE'Classes'Installer'Assemblies'Global
中的此位置 -
删除所有名为
Microsoft.SqlServer.Types
、的项,但在此之前请进行注册表备份注意不要弄乱注册表。 -
以管理员身份运行
Developer Command Prompt
并运行此命令gacutil -i Microsoft.SqlServer.Types
-
修复您现有的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";但它没有运行,因为它缺少一些安装包,所以我决定卸载(为了以后安装,我似乎无法安装,因为它抱怨安装了更新的版本)。所以我试着运行,即使没有这个版本,我的程序也能正常运行。