C# EF CodeFirst:参数@objname不明确或声明的@objtype(列)错误

C# EF CodeFirst:参数@objname不明确或声明的@objtype(列)错误,c#,entity-framework,ef-code-first,entity-framework-migrations,C#,Entity Framework,Ef Code First,Entity Framework Migrations,我有一个名为EducationTypes的表和一个名为EducationType的实体,我重命名了一个实体属性,现在我经常得到参数@objname不明确或声明的@objtype(列)错误。我如何解决这个问题 生成的SQL脚本: EXECUTE sp_rename @objname = N'dbo.EducationTypes.nvarchar', @newname = N'EducationTypeTitle', @objtype = N'COLUMN' 只是花了太多的时间试图弄清楚为什么这会

我有一个名为
EducationTypes
的表和一个名为
EducationType
的实体,我重命名了一个实体属性,现在我经常得到
参数@objname不明确或声明的@objtype(列)错误
。我如何解决这个问题

生成的SQL脚本:

EXECUTE sp_rename @objname = N'dbo.EducationTypes.nvarchar', @newname = N'EducationTypeTitle', @objtype = N'COLUMN'

只是花了太多的时间试图弄清楚为什么这会发生在一个只能通过mylittlesql访问的生产数据库上。无法重现该问题,但从sp_重命名的位制作了此脚本,以便下次发生时,我可以找到确切原因。是的,这太过分了,但可能会帮助其他人

如果您试图以某种方式将“[”或“]”输入存储在sys.columns中的实际列名中(列名为“?”nvarchar??),则会出现问题。PARSENAME不处理[]并返回null,因此sp_重命名将不起作用

这只会帮助诊断“column”案例的问题,错误代码为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
这将在(SSM或您正在使用的任何东西的)消息选项卡和结果选项卡中的表字段中输出一些有用的消息


祝您好运。

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

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

考虑到EF代码首先创建interference表,以使用派生interference表的表名来关联2个或多个表,因此当您使用使用像interference表这样的名称的类名时,我们将得到这种不明确的错误

例如,如果您有一个具有答案导航属性的问题类,则内部模型元数据将包含一个名为Question\u Answer的引用


要解决这个问题,请尝试更改类名(用于生成表)并确保它们的唯一性。

我在尝试使用Sql(“…”)方法重命名迁移脚本中的外键时,通过Entity Framework 6获得了这一点。我的解决方法是在名称周围使用方括号:

i、 e.改变这一点:

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”)时,这种情况就发生在我身上,并且所有迁移都工作得很好

发生在:

  • 添加了一个新迁移(migratoin1)
  • 更新了本地数据库
  • 然后删除了相同的迁移(migratoin1)
  • 然后使用相同的名称(migratoin1)添加另一个迁移
  • 然后应用到本地数据库并发布

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

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

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

并排除新名称上的括号(如您所做),否则它们将成为名称的一部分。顺便说一句,这在首先使用自动生成的代码迁移时也有效。我试图添加RenameIndex命令,因为我已经重命名了表,EF6不会自动重命名PK索引。这会在几个月后做其他事情时引发问题。因此,我必须添加一个显式重命名索引。直到我将[]放在索引的现有名称周围,它才起作用。一旦我这样做了,一切都很好。记住迁移也会创建一个生成的类。因此,不要创建与任何模型类同名的迁移:)或删除MigrationHstory表