EF SaveChanges 需要 .NET 3.5 SP1

.NET 3.5 SP1 required for EF SaveChanges

我将我的 .NET 项目目标设置为 .NET 4 Full。它适用于 Windows 7、8 和 10。

当我在安装了 .NET 4 和 SQL Express 2008 R2 的情况下尝试在 Windows XP 中使用它时,对 DbContext.SaveChanges() 的调用抛出一个异常提示

This functionality requires .NET Framework 3.5 SP1. Please install .NET Framework 3.5 SP1 to use this functionality.

安装 .NET 3.5 SP1 后错误消失。考虑到 .NET 3.5 SP1 安装包很大 (230 MB),我现在应该做什么以及为什么会出现这种情况?值得一提的是,我还安装了 .NET 4.0 KB2468871

完整异常信息:

An error occurred while updating the entries. See the inner exception for details.
   at System.Data.Entity.Internal.InternalContext.SaveChanges()
   at System.Data.Entity.Internal.LazyInternalContext.SaveChanges()
   at System.Data.Entity.DbContext.SaveChanges()
   at MyApp.Models.MyEntities.SaveChanges()


An error occurred while updating the entries. See the inner exception for details.
   at System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update()
   at System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.<Update>b__2(UpdateTranslator ut)
   at System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update[T](T noChangesResult, Func`2 updateFunction)
   at System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update()
   at System.Data.Entity.Core.Objects.ObjectContext.<SaveChangesToStore>b__d()
   at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
   at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesToStore(SaveOptions options, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction)
   at System.Data.Entity.Core.Objects.ObjectContext.<>c__DisplayClassb.<SaveChangesInternal>b__8()
   at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation)
   at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesInternal(SaveOptions options, Boolean executeInExistingTransaction)
   at System.Data.Entity.Core.Objects.ObjectContext.SaveChanges(SaveOptions options)
   at System.Data.Entity.Internal.InternalContext.SaveChanges()****


This functionality requires .NET Framework 3.5 SP1. Please install .NET Framework 3.5 SP1 to use this functionality.
The statement has been terminated.
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
   at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
   at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
   at System.Data.SqlClient.SqlDataReader.ConsumeMetaData()
   at System.Data.SqlClient.SqlDataReader.get_MetaData()
   at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
   at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)
   at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<Reader>b__c(DbCommand t, DbCommandInterceptionContext`1 c)
   at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed)
   at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(DbCommand command, DbCommandInterceptionContext interceptionContext)
   at System.Data.Entity.Internal.InterceptableDbCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)
   at System.Data.Entity.Core.Mapping.Update.Internal.DynamicUpdateCommand.Execute(Dictionary`2 identifierValues, List`1 generatedValues)
   at System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update()****

编辑

刚刚找到 this 遗憾的帖子:

Does you application need to use inside the database any of the following: Geography, Geometry or HierarchyId types, CLR-based User Defined Types, Functions, Aggregates, Triggers or Stored Procs?

If not, then there's nothing stopping you from using .NET Framework 4 to implement your application and using SQL Server 2008 R2 Express with it. It will work just fine with .NET Framework 4, for as long as you don't try to use CLR-based objects inside the database.

  • Krzysztof Kozielczyk, Program Manager for SQL Server Express

this

Does all SQL Server Express functionality work with .NET Framework 4 Beta 2?

No, there are few features that still require .NET Framework 2.0 SP2 or 3.5 SP1. These features will be disabled if .NET Framework 4 Beta 2 is the only .NET Framework on the machine, but will start working the moment .NET Framework 2.0 SP2 or 3.5 SP1 is installed.

The list of features that don’t work with .NET Framework 4 Beta 2:

The CLR data types geometry, geography, and hierarchyid.
The dynamic management views for assemblies and spatial objects.
The CLR user-defined types, functions, aggregates, procedures, and triggers.

Why some features don’t work with .NET Framework 4?

SQL Server Engine can only host one version of .NET Framework. In SQL Server 2008 it is .NET Framework 3.5 SP1. So hosting .NET Framework 4 Beta 2 in SP1 would mean that we no longer host .NET Framework 3.5 SP1. We simply don’t do this kind of breaking changes, since we try very hard to make sure that our Service Packs do not break any applications.

我的应用程序在其过程中使用了 HierarchyId,但它对 EF 隐藏了,因为它目前不支持它。

.NET 3.5 的这种依赖性不在您的代码中,它在 SQL 需要 .NET 3.5 的服务器客户端参考库中。我记得,安装 SQL 服务器管理对象或任何其他 .NET 库以访问 SQL 服务器需要 .NET 3.5,即使安装了 .NET 4。

这可能是 SQL 服务器库中的一个错误,它是 SQL 服务器的一部分,有人刚刚查找了 .NET 3.5 但没有设置为 .NET 3.5 或 +。

即使您设置项目的目标框架,也不会改变第三方库的依赖项。

没有不安装 .NET 3.5 的选择,您可以尝试的唯一选择是卸载与 SQL Server Express 旧版本相关的所有内容并安装较新版本 2014。

Akash Kava 的回答很好,我只是想补充一点,部署 .NET 应用程序的正确方法包括安装 .NET 3.5 和最新的 4.x 版本,以防止出现这种情况。

原因很简单: .NET 2.0 到 3.5 版本使用 CLR 2.0

从 4 到当前最新稳定版 4.5.2 的所有 .NET 版本都使用 CLR 4.0

这就是 .NET 4 不替换所有以前版本的原因,因此请同时安装 3.5 和 4 以使所有 .NET 应用程序和库与环境兼容。

这个问题没有明确的答案,但我找到了解决方法:

  • 在 Windows XP 上 .NET 2 SP2 随您的应用一起发布并将其与 .NET 4 一起安装。SQL 服务器将尝试加载 CLR2 并可以通过以下方式找到它.NET 2. .NET 2 的下载大小几乎是.NET 3.5 SP1 的十分之一。

  • 在 Windows 7 forward 上,使用 SQL Server 2012,它使用 .NET 4 安装的 CLR 4。因此不需要 .NET 2.0 或 3.5 SP1。