在实体框架中使用更新数据库时子查询返回超过 1 个值错误
Posted
技术标签:
【中文标题】在实体框架中使用更新数据库时子查询返回超过 1 个值错误【英文标题】:Subquery returned more than 1 value error when using Update-Database in Entity Framework 【发布时间】:2017-04-21 13:29:51 【问题描述】:我正在使用实体框架并尝试从 Visual Studio 中的包管理器控制台运行数据库迁移。当我这样做时,我收到以下错误和堆栈跟踪。
PM> Update-Database -Verbose 使用启动项目“项目”。使用 NuGet 项目“数据模型”。指定“-Verbose”标志以查看 应用于目标数据库的 SQL 语句。目标数据库 是:'数据库'(数据源:服务器,提供者:System.Data.SqlClient, 来源:配置)。应用显式迁移: [201612061704158_MigrationName]。应用显式迁移: 201612061704158_MigrationName。 ALTER TABLE [dbo].[TableName] 添加 [ColumnName] [bit] NOT NULL DEFAULT 0 System.Data.SqlClient.SqlException (0x80131904):子查询返回 超过 1 个值。当子查询跟随=时,这是不允许的 !=、、>= 或当子查询用作表达式时。这 声明已终止。在 System.Data.SqlClient.SqlConnection.OnError(SqlException 异常, Boolean breakConnection, Action
1 wrapCloseInAction) at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action
1 wrapCloseInAction) 在 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler、SqlDataReader 数据流、 BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean & dataReady) 在 System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(字符串 方法名,布尔异步,Int32 超时,布尔异步写入)在 System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry) at System.Data.SqlClient.SqlCommand.ExecuteNonQuery() at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<NonQuery>b__0(DbCommand t, DbCommandInterceptionContext
1 c) 在 System.Data.Entity.Infrastructure.Interception.InternalDispatcher1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func
3 操作,TInterceptionContext 拦截上下文, Action3 executing, Action
3 执行)在 System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.NonQuery(DbCommand 命令,DbCommandInterceptionContext 拦截上下文)在 System.Data.Entity.Internal.InterceptableDbCommand.ExecuteNonQuery() 在 System.Data.Entity.Migrations.DbMigrator.ExecuteSql(MigrationStatement migrationStatement、DbConnection 连接、DbTransaction 事务,DbInterceptionContext 拦截上下文)在 System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.ExecuteSql(MigrationStatement migrationStatement、DbConnection 连接、DbTransaction 事务,DbInterceptionContext 拦截上下文)在 System.Data.Entity.Migrations.DbMigrator.ExecuteStatementsInternal(IEnumerable1 migrationStatements, DbConnection connection, DbTransaction transaction, DbInterceptionContext interceptionContext) at System.Data.Entity.Migrations.DbMigrator.ExecuteStatementsWithinTransaction(IEnumerable
1 migrationStatements、DbTransaction 事务、DbInterceptionContext 拦截上下文)在 System.Data.Entity.Migrations.DbMigrator.ExecuteStatementsWithinNewTransaction(IEnumerable1 migrationStatements, DbConnection connection, DbInterceptionContext interceptionContext) at System.Data.Entity.Migrations.DbMigrator.ExecuteStatementsInternal(IEnumerable
1 migrationStatements、DbConnection 连接、DbInterceptionContext 拦截上下文)在 System.Data.Entity.Migrations.DbMigrator.ExecuteStatementsInternal(IEnumerable1 migrationStatements, DbConnection connection) at System.Data.Entity.Migrations.DbMigrator.<>c__DisplayClass30.<ExecuteStatements>b__2e() at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.<>c__DisplayClass1.<Execute>b__0() at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func
1 操作)在 System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute(操作 操作)在 System.Data.Entity.Migrations.DbMigrator.ExecuteStatements(IEnumerable1 migrationStatements, DbTransaction existingTransaction) at System.Data.Entity.Migrations.DbMigrator.ExecuteStatements(IEnumerable
1 迁移声明)在 System.Data.Entity.Migrations.Infrastructure.MigratorBase.ExecuteStatements(IEnumerable1 migrationStatements) at System.Data.Entity.Migrations.DbMigrator.ExecuteOperations(String migrationId, VersionedModel targetModel, IEnumerable
1 操作, IEnumerable1 systemOperations, Boolean downgrading, Boolean auto) at System.Data.Entity.Migrations.DbMigrator.ApplyMigration(DbMigration migration, DbMigration lastMigration) at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.ApplyMigration(DbMigration migration, DbMigration lastMigration) at System.Data.Entity.Migrations.DbMigrator.Upgrade(IEnumerable
1 pendingMigrations, 字符串 targetMigrationId, 字符串 lastMigrationId) 在 System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.Upgrade(IEnumerable`1 pendingMigrations, 字符串 targetMigrationId, 字符串 lastMigrationId) 在 System.Data.Entity.Migrations.DbMigrator.UpdateInternal(字符串 目标迁移)在 System.Data.Entity.Migrations.DbMigrator.c__DisplayClassc.b__b() 在 System.Data.Entity.Migrations.DbMigrator.EnsureDatabaseExists(操作 mustSucceedToKeepDatabase) 在 System.Data.Entity.Migrations.Infrastructure.MigratorBase.EnsureDatabaseExists(操作 mustSucceedToKeepDatabase) 在 System.Data.Entity.Migrations.DbMigrator.Update(字符串 目标迁移)在 System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update(字符串 目标迁移)在 System.Data.Entity.Migrations.Design.ToolingFacade.UpdateRunner.Run() 在 System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate) 在 System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate) 在 System.Data.Entity.Migrations.Design.ToolingFacade.Run(BaseRunner 亚军)在 System.Data.Entity.Migrations.Design.ToolingFacade.Update(字符串 targetMigration,布尔力)在 System.Data.Entity.Migrations.UpdateDatabaseCommand.c__DisplayClass2.<.ctor>b__0() 在 System.Data.Entity.Migrations.MigrationsDomainCommand.Execute(操作 命令)ClientConnectionId:40e2fc22-5bbd-4d83-88f3-ce5b2bc378dc 错误 Number:512,State:1,Class:16 子查询返回超过 1 个值。这 当子查询跟随 =、!=、、>= 或 当子查询用作表达式时。该声明已 终止。
我不知道这里发生了什么。直接运行SQL语句就可以了
ALTER TABLE [dbo].[TableName] ADD [ColumnName] [bit] NOT NULL DEFAULT 0
这就是迁移文件的样子
public partial class MigrationName : DbMigration
public override void Up()
AddColumn("dbo.TableName", "ColumnName", c => c.Boolean(nullable: false));
public override void Down()
DropColumn("dbo.TableName", "ColumnName");
如果我再注释掉迁移文件中Up()
的内容,就可以成功运行(空)迁移了。
另外,如果我针对空数据库运行所有迁移,包括这次迁移,一切正常。所以导致错误的数据存在一些问题(这是预期的,给定错误消息)。
我已尝试查看 SQL Server Profiler 以尝试找出正在执行的 SQL,但没有任何显示。
到目前为止,我还有大约 20 个其他迁移运行良好,但是这个和上一个一直在抛出这个错误。
有谁知道潜在的问题可能是什么,或者我如何才能获得有关问题所在的更多信息?
【问题讨论】:
[TableName]
上是否有任何触发器?
@Blorgbeard 好问题。有,但如果我放弃它,迁移也会以同样的方式失败。
【参考方案1】:
我的连接字符串设置了MultipleActiveResultSets=True
。从连接字符串中删除它解决了这个问题。
【讨论】:
【参考方案2】:您是否尝试自己编写迁移。我会做这样的事情
public override void Up()
DropColumn("dbo.TablaName", "ColumnName");
AddColumn("dbo.TableName", "ColumnName", c => c.Boolean(nullable: false));
或
public override void Up()
AlterColumn("dbo.TableName", "ColumnName", c => c.Boolean(nullable: false));
或者只是添加一列
public override void Up()
DropColumn("dbo.TablaName", "ColumnName");
AddColumn("dbo.TableName", "ColumnName", c => c.Boolean(nullable: false));
我会把 Down 留空。
public override void Down()
干杯!
【讨论】:
好吧,该列不存在,这就是我尝试添加它的原因。将迁移更改为您的会导致ALTER TABLE DROP COLUMN failed because column 'ColumnName' does not exist in table 'TableName'.
因此,如果您想要做的只是一列,那么只需使用 AddColumn("NAME_OF_YOUR_TABLE", "NAME_OF_YOUR_COLUMN", c=>c.Boolean(nullable: false)
并将 Down 留空
仅供参考,您需要将 ColumnName 替换为您正在使用的列的名称。
这正是我的问题。
好的,你有多少个迁移文件?因为如果您有待处理的迁移文件,它将无法工作。因此,请尝试查找除了最新的迁移之外是否还有任何待处理的迁移【参考方案3】:
按照 Kris 的建议,更改连接字符串也对我有用,但我担心这会如何影响使用相同连接字符串的其他任何内容。
对我也有用的是清空Up()
和Down()
方法,运行迁移并使用update-database -targetmigration:"PreviousMigrationName"
回滚到上一个迁移。完成此操作后,我可以重新创建迁移并在不更改连接字符串的情况下运行它。
【讨论】:
以上是关于在实体框架中使用更新数据库时子查询返回超过 1 个值错误的主要内容,如果未能解决你的问题,请参考以下文章