EF CodeFirst:参数@objname不明确,或者声明的@objtype(COLUMN)错误
本文关键字:@objtype COLUMN 错误 声明 或者 CodeFirst 参数 @objname 不明确 EF | 更新日期: 2023-09-27 17:58:58
我有一个名为EducationTypes
的表和一个名为EducationType
的实体,我重命名了其中一个实体属性,现在我经常得到Either the parameter @objname is ambiguous or the claimed @objtype (COLUMN) is wrong
。我该如何解决这个问题?
生成的SQL脚本:
EXECUTE sp_rename @objname = N'dbo.EducationTypes.nvarchar', @newname = N'EducationTypeTitle', @objtype = N'COLUMN'
如果您使用的是Code First,并且有一个现有的迁移脚本,并且试图覆盖已删除的更改(即重命名列),那么您将得到错误输出。最简单的方法是删除迁移脚本,通过NuGet添加迁移,然后更新数据库。
这是因为当自动创建表和…时,类(模型)名称与其他保留或生成的名称发生冲突。
考虑到EF Code First使用派生interaction表的表名创建interaction表以关联2个或多个表,因此当您使用与interaction表类似的名称的类名时,我们会得到这样一个不明确的错误。
例如,如果您有一个Question类,该类具有Answer导航属性,则内部模型元数据将包含一个名为Question_Answer的引用
要解决此问题,请尝试更改类名(用于生成表)并确保其唯一性。
我在尝试使用Sql("…")方法重命名迁移脚本中的外键时,在Entity Framework 6中遇到了这个问题。我的解决方法是在名称周围使用方括号:
即更改:
sp_rename 'FK_dbo.tablename_dbo.othertablename_fieldname', 'FK_dbo.tablename_dbo.othertablenewname_fieldnewname', 'object'
到此:
sp_rename '[FK_dbo.tablename_dbo.othertablename_fieldname]', 'FK_dbo.tablename_dbo.othertablenewname_fieldnewname', 'object'
SQL Server就能够找到外键。
避开迁移标题中的保留字或类名。
当我将迁移命名为"Init"(重命名为"InitialCreate")时,就发生了这种情况。
只是花了太多时间试图弄清楚为什么会在我只能通过mylittlesql访问的生产数据库上发生这种情况。无法重现此问题,但使用sp_rename的部分编写了此脚本,因此下次发生此问题时,我可以确切地找出原因。是的太夸张了,但可能会帮助其他人。
如果您设法将"["或"]"放入存储在sys.columns中的实际列名中,就会出现问题(?"nvarchar"作为您的列名???)。PARSENAME无法处理[]的并返回null,因此sp_rename将不起作用。
这只会帮助诊断错误代码为15248的"列"情况的问题,这就是我一直存在的问题:
declare @objname nvarchar(1035) = N'dbo.EducationTypes.nvarchar' -- input to sp_rename
declare @newname sysname = N'EducationTypeTitle' -- input to sp_rename
declare @UnqualOldName sysname,
@QualName1 sysname,
@QualName2 sysname,
@QualName3 sysname,
@OwnAndObjName nvarchar(517),
@SchemaAndTypeName nvarchar(517),
@objid int,
@xtype nchar(2),
@colid int,
@retcode int
select @UnqualOldName = parsename(@objname, 1),
@QualName1 = parsename(@objname, 2),
@QualName2 = parsename(@objname, 3),
@QualName3 = parsename(@objname, 4)
print 'Old Object Name = ''' + convert(varchar,isnull(@UnqualOldName ,'')) + ''''
-- checks that parsename is getting the right name out of your @objname parameter
print 'Table name:'
if @QualName2 is not null
begin
print QuoteName(@QualName2) +'.'+ QuoteName(@QualName1)
select @objid = object_id(QuoteName(@QualName2) +'.'+ QuoteName(@QualName1))
end
else
begin
print QuoteName(@QualName1)
select @objid = object_id(QuoteName(@QualName1))
end
-- check if table is found ok
print 'Table Object ID = ''' + convert(varchar,isnull(@objid ,-1)) + ''''
select @xtype = type from sys.objects where object_id = @objid
print '@xtype = ''' + convert(varchar,isnull(@xtype,'')) + ''' (U or V?)'
if (@xtype in ('U','V'))
begin
print 'select @colid = column_id from sys.columns where object_id = ' +
convert(varchar,isnull(@objid,0)) + ' and name = ''' +
@UnqualOldName + ''''
select * from sys.columns where object_id = @objid -- and name = @UnqualOldName
select @colid = column_id from sys.columns
where object_id = @objid and name = @UnqualOldName
print 'Column ID = ''' + convert(varchar,isnull(@colid,-1)) + ''''
end
这将在消息选项卡(SSMS或您正在使用的任何东西)和结果选项卡中的表格字段中输出一些有用的消息。
祝你好运。
我刚刚遇到了同样的问题,也是在重构之后。对我来说,这个问题是由迁移引起的,迁移也被重构了。
结果是无法执行另一个迁移,因为该迁移通过搜索表的旧名称来查找表。
恢复迁移中的更改解决了此问题。
实际上,当您刚刚删除数据库时,也会发生此错误,并且您的上下文没有意识到您的数据库不在那里。
我重新创建了数据库,现在错误得到了解决。
附言:当您尝试运行更新数据库时,请确保您检查数据库是否仍在那里
对我来说,它发生在:
- 添加了新的迁移(migrateoin1)
- 在本地数据库上更新
- 然后删除了相同的迁移(migratein1)
- 然后添加了相同名称(migrateoin1)的另一个迁移
- 然后应用到本地数据库并发布
删除迁移文件(migrateoin1)解决了我的问题。
我刚刚遇到了这个错误,并解决了这个问题——修改迁移分部类,迁移试图重命名索引,但索引不存在,我只是这样更改迁移代码:
- 删除索引方法上的重命名
- 在向上空白中设置创建索引
- 在Down空白中设置放置索引
这解决了我的问题。
我在第一次使用代码更新数据库时遇到了这个错误。我用一个外键创建了一个表,其他人重命名了那个外键。现在,当我尝试更新数据库时,它抛出了这个异常。
我执行了以下步骤来克服这个问题:
- 不得不从我的数据库中删除那个表
- 跟踪哪个迁移添加了该表并将其从SQL server中的迁移历史记录中删除
- 最后再次运行更新数据库,我的数据库更新成功
我解决了这个错误,从SQL server中的"我的数据库迁移历史记录表"中删除了所有旧的迁移,然后添加了一个新的迁移,但只针对所需的更改,然后更新了数据库。它运行良好。
我遇到了这种情况,因为自动迁移被设置为true,而其中一名新程序员向项目添加了迁移,因此在更新数据库时会感到困惑。通过从项目中删除现有的迁移并再次依靠自动更新来解决问题。