EF5 Code First – Modification d’un type de colonne avec des migrations

Je suis nouveau sur EF5 Code First et je bricole avec une preuve de concept avant de me lancer dans un projet.

J’ai initialement créé un modèle qui ressemblait à quelque chose comme

public class Person { public int Id { get; set; } public ssortingng FirstName { get; set;} public ssortingng Surname {get;set;} public ssortingng Location {get;set;} } 

Et j’ai ajouté quelques disques en utilisant une petite application MVC que j’ai collée au sumt.

Maintenant, je veux changer la colonne Location en une énumération, quelque chose comme:

 public class Person { public int Id { get; set; } public ssortingng FirstName { get; set;} public ssortingng Surname {get;set;} public Locations Location {get;set;} } public enum Locations { London = 1, Edinburgh = 2, Cardiff = 3 } 

Lorsque j’ajoute la nouvelle migration, je reçois:

 AlterColumn("dbo.People", "Location", c => c.Int(nullable: false)); 

mais quand j’exécute update-database je reçois une erreur

 Conversion failed when converting the nvarchar value 'London' to data type int. 

Existe-t-il un moyen dans la migration de tronquer la table avant qu’elle n’exécute l’instruction alter?

Je sais que je peux ouvrir la firebase database et le faire manuellement, mais existe-t-il un moyen plus intelligent?

Le moyen le plus intelligent est probablement de ne pas modifier les types. Si vous avez besoin de faire cela, je vous suggère de suivre les étapes suivantes:

  1. Ajouter une nouvelle colonne avec votre nouveau type
  2. Utilisez Sql() pour reprendre les données de la colonne d’origine à l’aide d’une instruction update
  3. Supprimer l’ancienne colonne
  4. Renommez la nouvelle colonne

Tout cela peut être fait dans la même migration, le script SQL correct sera créé. Vous pouvez ignorer l’étape 2 si vous souhaitez que vos données soient supprimées. Si vous souhaitez en prendre le contrôle, ajoutez l’instruction appropriée (peut également contenir une instruction switch).

Malheureusement, Code First Migrations ne fournit pas de moyens plus simples pour accomplir cela.

Voici l’exemple de code:

 AddColumn("dbo.People", "LocationTmp", c => c.Int(nullable: false)); Sql(@" UPDATE dbp.People SET LocationTmp = CASE Location WHEN 'London' THEN 1 WHEN 'Edinburgh' THEN 2 WHEN 'Cardiff' THEN 3 ELSE 0 END "); DropColumn("dbo.People", "Location"); RenameColumn("dbo.People", "LocationTmp", "Location"); 

Basé sur la réponse de @ JustAnotherUserYouMayKnow, mais plus facile.

Essayez d’exécuter d’abord la commande Sql() puis AlterColumn() :

 Sql(@" UPDATE dbo.People SET Location = CASE Location WHEN 'London' THEN 1 WHEN 'Edinburgh' THEN 2 WHEN 'Cardiff' THEN 3 ELSE 0 END "); AlterColumn("dbo.People", "Location", c => c.Int(nullable: false)); 

Je sais que cela ne s’applique pas directement à la question, mais pourrait être utile à quelqu’un. Dans mon problème, j’ai accidentellement transformé un champ année en date-heure et j’essayais de comprendre comment supprimer toutes les données, puis basculer le type de données sur un int.

Lors d’une migration par ajout, EF souhaitait simplement mettre à jour la colonne. Je devais supprimer ce qu’ils voulaient faire et append mon propre code. En gros, je viens de supprimer la colonne et d’en append une nouvelle. Voici ce qui a fonctionné pour moi.

 protected override void Up(MigrationBuilder migrationBuilder) { migrationBuilder.DropColumn( name: "TestingPeriodYear", table: "ControlActivityIssue"); migrationBuilder.AddColumn( name: "TestingPeriodYear", table: "ControlActivityIssue", nullable: true); } protected override void Down(MigrationBuilder migrationBuilder) { migrationBuilder.DropColumn( name: "TestingPeriodYear", table: "ControlActivityIssue"); migrationBuilder.AddColumn( name: "TestingPeriodYear", table: "ControlActivityIssue", nullable: true); }