EF CodeFirst:参数@objname不明确或声称@objtype(COLUMN)错误

时间:2013-02-13 07:21:29

标签: c# entity-framework ef-code-first ef-migrations

我有一个名为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'

10 个答案:

答案 0 :(得分:29)

如果您正在使用Code First并且拥有(一个)现有的迁移脚本,并且正在尝试覆盖已被删除的更改(即重命名列),那么您将获得该错误输出。最简单的方法是删除迁移脚本,通过NuGet添加迁移,然后更新数据库。

答案 1 :(得分:10)

这是因为名称冲突类(模型)名称与其他保留或生成的名称冲突时,自动创建表格和......。

考虑到EF Code First创建了干预表,使用派生干预表的表名来关联2个或更多个表,所以当你使用一个使用类似干预表的名称的类名时,我们会得到这样的这个模棱两可的错误。

例如,如果您的 Question 类具有 Answer 导航属性,则内部模型元数据将包含名为 QUESTION_ANSWER 的引用

要解决此问题,请尝试更改类名(用于生成表)并确保其唯一性。

答案 2 :(得分:3)

在尝试使用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就能找到外键。

答案 3 :(得分:2)

花了太多时间试图弄清楚为什么在生产数据库上发生这种情况我只能通过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或您正在使用的任何内容)和“结果”选项卡中的表字段中输出一些有用的消息。

祝你好运。

答案 4 :(得分:1)

在重构之后,我也遇到了同样的问题。对我来说,问题是由重构的迁移引起的。

结果是无法执行另一次迁移,因为该迁移是通过搜索旧名来查找表。

恢复迁移中的更改解决了这个问题。

答案 5 :(得分:1)

请避免在迁移标题中保留字或类名。

当我将迁移命名为“ Init”时,这发生在我身上-重命名为“ InitialCreate”,并且一切运行正常

答案 6 :(得分:0)

实际上,当您刚删除数据库时,也会发生此错误,并且您的上下文没有意识到您的数据库不存在。

我重新创建了数据库,现在错误已解决。

P.S。当您尝试运行update-database

时,请确保检查数据库是否仍然存在

答案 7 :(得分:0)

对我来说,它发生在以下时间:

  • 添加了新的迁移(migratoin1)
  • 在本地数据库上更新
  • 然后删除了相同的迁移(migratoin1)
  • 然后以相同的名称(migratoin1)添加了另一个迁移
  • 然后将其应用于本地数据库并发布。

删除迁移文件(migratoin1)解决了我的问题。

答案 8 :(得分:0)

这是发生在我身上的原因,因为自动迁移设置为true,并且其中一位程序员是新添加的项目迁移,因此在更新数据库时会感到困惑。 通过从项目中删除现有的迁移并再次依靠自动更新来解决该问题。

答案 9 :(得分:-1)

我通过从SQL Server的“我的数据库迁移历史记录”表中删除所有旧迁移,然后添加一个新迁移(但仅针对所需的更改)然后更新数据库来解决此错误。