2012-08-02 11 views
11

Say, stiamo usando EF Codice Prima e abbiamo questo semplice modello:EF primo codice 5.0.rc Migrazioni doesn`t proprietà aggiornamento Identità

using System; 
using System.Collections.Generic; 
using System.ComponentModel.DataAnnotations; 
using System.Data.Entity; 
using System.Linq; 
using System.Web; 

namespace EFCodeFirstIdentityProblem.Models 
{ 
    public class CAddress 
    { 
     public int ID { get; set; } 

     public string Street { get; set; } 
     public string Building { get; set; } 

     public virtual CUser User { get; set; } 
    } 

    public class CUser 
    { 
     public int ID { get; set; } 

     public string Name { get; set; } 
     public string Age { get; set; } 

     [Required] 
     public virtual CAddress Address { get; set; } 
    } 

    public class MyContext : DbContext 
    { 
     public DbSet<CAddress> Addresses { get; set; } 
     public DbSet<CUser> Users { get; set; } 
    } 
} 


Ti piace questa, CAddress sarebbe principale fine di questa relazione 1: 0..1. Quindi aggiungiamo la stringa di connessione a Web.Config (utilizzo MSSQL 2008 R2), eseguo un controller che utilizza questo modello. EF Codice primo crea le tabelle per noi come ci si aspettava:

enter image description here enter image description here



Quindi, supponiamo che abbiamo fatto un errore, e in effetti vogliamo CUser di essere principale fine di questo Relazione 0..1: 1. Così facciamo cambiamenti:

 ... 
     [Required] 
     public virtual CUser User { get; set; } 
     ... 

     ... 
     public virtual CAddress Address { get; set; } 
     ... 

costruire, poi in corsa Console Package Manager e aggiungere un po di migrazione:

PM> Enable-Migrations 
Checking if the context targets an existing database... 
Detected database created with a database initializer. Scaffolded migration '201208021053489_InitialCreate' corresponding to existing database. To use an automatic migration instead, delete the Migrations folder and re-run Enable-Migrations specifying the -EnableAutomaticMigrations parameter. 
Code First Migrations enabled for project EFCodeFirstIdentityProblem. 
PM> Add-Migration ChangeDependency 
Scaffolding migration 'ChangeDependency'. 
The Designer Code for this migration file includes a snapshot of your current Code First model. This snapshot is used to calculate the changes to your model when you scaffold the next migration. If you make additional changes to your model that you want to include in this migration, then you can re-scaffold it by running 'Add-Migration 201208021157341_ChangeDependency' again. 
PM> 

Ecco che cosa `VE stato dato per "ChangeDependency" migrazione:

namespace EFCodeFirstIdentityProblem.Migrations 
{ 
    using System; 
    using System.Data.Entity.Migrations; 

    public partial class ChangeDependency : DbMigration 
    { 
     public override void Up() 
     { 
      DropForeignKey("dbo.CUsers", "ID", "dbo.CAddresses"); 
      DropIndex("dbo.CUsers", new[] { "ID" }); 
      AlterColumn("dbo.CAddresses", "ID", c => c.Int(nullable: false)); 
      AlterColumn("dbo.CUsers", "ID", c => c.Int(nullable: false, identity: true)); //identity: true - this is important 
      AddForeignKey("dbo.CAddresses", "ID", "dbo.CUsers", "ID"); 
      CreateIndex("dbo.CAddresses", "ID"); 
     } 

     public override void Down() 
     { 
      DropIndex("dbo.CAddresses", new[] { "ID" }); 
      DropForeignKey("dbo.CAddresses", "ID", "dbo.CUsers"); 
      AlterColumn("dbo.CUsers", "ID", c => c.Int(nullable: false)); 
      AlterColumn("dbo.CAddresses", "ID", c => c.Int(nullable: false, identity: true)); 
      CreateIndex("dbo.CUsers", "ID"); 
      AddForeignKey("dbo.CUsers", "ID", "dbo.CAddresses", "ID"); 
     } 
    } 
} 

L'importazione e la parte è:

AlterColumn ("dbo.CUsers", "ID", c => c.Int (nullable: false, identità: true));

Quindi CUsers.ID deve ora diventare Identity in DB. Cerchiamo di commettere questo cambia in DB:

PM> 
PM> Update-Database -Verbose 
Using StartUp project 'EFCodeFirstIdentityProblem'. 
Using NuGet project 'EFCodeFirstIdentityProblem'. 
Specify the '-Verbose' flag to view the SQL statements being applied to the target database. 
Target database is: 'EFTest' (DataSource: (local), Provider: System.Data.SqlClient, Origin: Configuration). 
Applying code-based migrations: [201208021157341_ChangeDependency]. 
Applying code-based migration: 201208021157341_ChangeDependency. 
ALTER TABLE [dbo].[CUsers] DROP CONSTRAINT [FK_dbo.CUsers_dbo.CAddresses_ID] 
DROP INDEX [IX_ID] ON [dbo].[CUsers] 
ALTER TABLE [dbo].[CAddresses] ALTER COLUMN [ID] [int] NOT NULL 
ALTER TABLE [dbo].[CUsers] ALTER COLUMN [ID] [int] NOT NULL 
ALTER TABLE [dbo].[CAddresses] ADD CONSTRAINT [FK_dbo.CAddresses_dbo.CUsers_ID] FOREIGN KEY ([ID]) REFERENCES [dbo].[CUsers] ([ID]) 
CREATE INDEX [IX_ID] ON [dbo].[CAddresses]([ID]) 
[Inserting migration history record] 
Running Seed method. 
PM> 

non ci sono istruzioni SQL fornite dal Migrazioni di CUsers.ID diventando colonna Identity nel DB. Così, a causa di questo c'è un problema:

(database aggiornato) enter image description here enter image description here

Quindi, l'utente è fine principale ora, e deve avere ID Identità: "SI" di bandiera, ma l'identità è ancora "NO". E l'indirizzo è dipendente dalla fine, deve avere l'identità ID "NO", ma è ancora "SÌ". Quindi non posso aggiungere una nuova tabella User to User, perché il nuovo ID non viene generato per la nuova istanza.

Se si elimina un intero database, il codice EF innanzitutto crea nuove tabelle da zero correttamente, quindi questo è un problema solo delle migrazioni.

Cosa faccio in questa situazione? Questo bug di Migrazione EF è?

risposta

22

Non sono sicuro se si tratta di un errore perché c'è un altro problema: è cannot alter existing column to identity or remove identity. Posso immaginare che questo sia considerato come una migrazione completamente manuale per chiarire che è necessario spostare i dati.

+1

Wow, è un peccato. Non lo sapevo. La ringrazio per la risposta. – Roman

+1

spunta indietro non cita le virgolette – d512

Problemi correlati