【问题标题】:EF CodeFirst: Either the parameter @objname is ambiguous or the claimed @objtype (COLUMN) is wrongEF CodeFirst:参数@objname 不明确或声明的@objtype (COLUMN) 错误
【发布时间】:2013-01-28 16:39:31
【问题描述】:

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

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

    • 或者删除MigrationHsitory表
    • 如何通过 Nuget 添加迁移?你能详细说明一下吗?
    • @SuatAtanPhD 从工具栏;工具 -> NuGet 包管理器 -> 包管理器控制台。然后,在包管理器控制台运行: Add-Migration Name-Your-Migration-Here ,不要忘记更新后: Update-Database
    【解决方案2】:

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

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

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

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

    【讨论】:

    • 请记住,迁移也会创建生成的类。所以不要创建与任何模型类同名的迁移:)
    【解决方案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 然后能够找到外键。

    【讨论】:

    • 并排除新名称上的括号(如您所做的那样),否则它们将成为名称的一部分
    • 顺便说一句,这在使用自动生成的代码优先迁移时也有效。我试图添加一个 RenameIndex 命令,因为我已重命名表并且 EF6 不会自动重命名 PK 索引。这在几个月后在做其他事情时引起了问题。所以我不得不添加一个显式的 RenameIndex。直到我将 [] 放在索引的现有名称周围,它才起作用。一旦我这样做了,一切都很棒。
    【解决方案4】:

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

    祝你好运。

    【讨论】:

      【解决方案5】:

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

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

      还原迁移中的更改解决了这个问题。

      【讨论】:

        【解决方案6】:

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

        当我将迁移命名为“Init”时发生这种情况 - 重命名为“InitialCreate”并且一切正常

        【讨论】:

          【解决方案7】:

          其实这个错误也发生在你刚刚删除数据库的时候,而你的上下文并没有意识到你的数据库不存在。

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

          附:确保在尝试运行更新数据库时检查数据库是否仍然存在

          【讨论】:

            【解决方案8】:

            对我来说,它发生在:

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

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

            【讨论】:

              【解决方案9】:

              我刚刚遇到这个错误并解决了这个修改迁移部分类,迁移尝试重命名索引并且索引不存在,我只是像这样更改迁移代码:

              1. 删除索引方法上的重命名
              2. 在 Up void 中设置创建索引
              3. 在 Down void 中设置 drop index

              这解决了我的问题。

              【讨论】:

                【解决方案10】:

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

                【讨论】:

                  【解决方案11】:

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

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2015-02-20
                    相关资源
                    最近更新 更多