web-dev-qa-db-fra.com

EF CodeFirst: le paramètre @objname est ambigu ou le prétendu @objtype (COLUMN) est incorrect.

J'ai une table nommée EducationTypes et une entité nommée EducationType, j'ai renommé l'une des propriétés de l'entité, maintenant je reçois fréquemment Either the parameter @objname is ambiguous or the claimed @objtype (COLUMN) is wrong. Comment puis-je résoudre ce problème?

Le script SQL généré:

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

Si vous utilisez Code First et que vous avez un (des) script (s) de migration existant (s) et que vous essayez d'écraser une modification (c'est-à-dire, renommer une colonne) qui a été supprimée depuis, vous obtiendrez ce résultat d'erreur. La méthode la plus simple consiste à supprimer le script de migration, Add-Migration via NuGet, puis à mettre à jour la base de données.

26
RizJa

Cela est dû à name Conflict de noms de classe (modèle) avec d'autres noms réservés ou générés, lors de la création automatique des tables et ....

Considérant que EF Code First crée les tables intervenues pour relier deux tables ou plus en utilisant le nom des tables pour la table intervenante dérivée, vous obtiendrez ainsi cette erreur ambiguë lorsque vous utilisez un nom de classe qui utilise un nom similaire aux tables intervenantes.

Par exemple, si vous avez une classe Question dotée d'une propriété de navigation Answer, les métadonnées du modèle interne contiendront une référence appelée QUESTION_ANSWER.

Pour résoudre ceci, essayez de changer les noms de classe (utilisés pour générer des tables) et assurez-vous de leur unicité.

10
Amirhossein Mehrvarzi

Je l'ai compris avec Entity Framework 6 lorsque je tentais de renommer une clé étrangère dans mon script de migration à l'aide de la méthode Sql ("..."). La solution de contournement que j’avais était d’utiliser des crochets autour du nom:

c'est-à-dire changer ceci:

sp_rename 'FK_dbo.tablename_dbo.othertablename_fieldname', 'FK_dbo.tablename_dbo.othertablenewname_fieldnewname', 'object'

...pour ça:

sp_rename '[FK_dbo.tablename_dbo.othertablename_fieldname]', 'FK_dbo.tablename_dbo.othertablenewname_fieldnewname', 'object'

SQL Server est alors capable de trouver la clé étrangère.

3
garryp

Je viens de passer trop de temps à essayer de comprendre pourquoi cela se produisait dans une base de données de production, je ne peux y accéder que via mylittlesql. Impossible de reproduire le problème, mais a créé ce script à partir de bits de sp_rename. Ainsi, la prochaine fois que cela se produira, je saurai exactement pourquoi. Oui, c'est exagéré, mais pourrait aider quelqu'un d'autre.

Il y a un problème si vous parvenez d'une manière ou d'une autre à obtenir '[ou'] 'dans le nom de colonne réel tel qu'il est stocké dans sys.columns, PARSENAME ne gère pas les commandes de [] et renvoie null, ainsi sp_rename ne fonctionnera pas.

Cela ne fera qu'aider à diagnostiquer le problème pour le cas de la "colonne" avec le code d'erreur 15248 qui est l'endroit où je continue à avoir ce problème:

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

Cela générera des messages utiles dans l'onglet Messages (de SSMS ou celui que vous utilisez) et dans les champs de table de l'onglet Résultats. 

Bonne chance.

2
MDWeb

Je viens d'avoir le même problème, également après refactoring. Pour moi, le problème a été causé par une migration qui a également été refactorisée.

En conséquence, une autre migration n'a pas pu être exécutée car cette migration recherchait une table en recherchant son ancien nom.

Annuler les modifications de la migration a résolu ce problème.

1
Br2

En réalité, cette erreur se produit également lorsque vous venez de supprimer la base de données et votre contexte ne réalise pas que votre base de données n’est pas présente.

J'ai recréé la base de données, et maintenant l'erreur était résolue.

P.S. assurez-vous de vérifier que la base de données est toujours présente lorsque vous essayez d'exécuter la base de données update

0
radu florescu

Évitez les mots réservés ou les noms de classe dans le titre de votre migration.

Cela m'est arrivé quand j'ai nommé une migration "Init" - renommée "InitialCreate" et tout fonctionnait parfaitement

0
ShhTot