Entity Framework
Prime migrazioni del codice quadro di entità
Ricerca…
Abilita migrazioni
Per abilitare le migrazioni Code First nel framework entità, utilizzare il comando
Enable-Migrations
sulla console di Gestione pacchetti .
È necessario disporre di un'implementazione DbContext
valida contenente gli oggetti del database gestiti da EF. In questo esempio il contesto del database conterrà oggetti BlogPost
e Author
:
internal class DatabaseContext: DbContext
{
public DbSet<Author> Authors { get; set; }
public DbSet<BlogPost> BlogPosts { get; set; }
}
Dopo aver eseguito il comando, dovrebbe apparire il seguente output:
PM> Enable-Migrations
Checking if the context targets an existing database...
Code First Migrations enabled for project <YourProjectName>.
PM>
Inoltre, una nuova cartella Migrations
dovrebbe apparire con un singolo file Configuration.cs
all'interno:
Il prossimo passo sarebbe quello di creare il tuo primo script di migrazione del database che creerà il database iniziale (vedi prossimo esempio).
Aggiungi la tua prima migrazione
Dopo aver abilitato le migrazioni (fare riferimento a questo esempio ), è ora possibile creare la prima migrazione contenente una creazione iniziale di tutte le tabelle, gli indici e le connessioni del database.
È possibile creare una migrazione utilizzando il comando
Add-Migration <migration-name>
Questo comando creerà una nuova classe contenente due metodi Up
e Down
che vengono utilizzati per applicare e rimuovere la migrazione.
Ora applica il comando basato sull'esempio precedente per creare una migrazione denominata Iniziale :
PM> Add-Migration Initial
Scaffolding migration 'Initial'.
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 Initial' again.
Viene creato un nuovo timestamp del file _Initial.cs (vengono mostrati solo gli elementi importanti qui):
public override void Up()
{
CreateTable(
"dbo.Authors",
c => new
{
AuthorId = c.Int(nullable: false, identity: true),
Name = c.String(maxLength: 128),
})
.PrimaryKey(t => t.AuthorId);
CreateTable(
"dbo.BlogPosts",
c => new
{
Id = c.Int(nullable: false, identity: true),
Title = c.String(nullable: false, maxLength: 128),
Message = c.String(),
Author_AuthorId = c.Int(),
})
.PrimaryKey(t => t.Id)
.ForeignKey("dbo.Authors", t => t.Author_AuthorId)
.Index(t => t.Author_AuthorId);
}
public override void Down()
{
DropForeignKey("dbo.BlogPosts", "Author_AuthorId", "dbo.Authors");
DropIndex("dbo.BlogPosts", new[] { "Author_AuthorId" });
DropTable("dbo.BlogPosts");
DropTable("dbo.Authors");
}
Come puoi vedere, nel metodo Up()
due tabelle vengono create Authors
e BlogPosts
e i campi vengono creati di conseguenza. Inoltre, la relazione tra le due tabelle viene creata aggiungendo il campo Author_AuthorId
. Dall'altro lato, il metodo Down()
tenta di invertire le attività di migrazione.
Se ti senti sicuro della migrazione, puoi applicare la migrazione al database utilizzando il comando:
Update-Database
Tutte le migrazioni in sospeso (in questo caso l' iniziale -migrazione) vengono applicate al database e successivamente viene applicato il metodo seed (l'esempio appropriato)
PM> update-database
Specify the '-Verbose' flag to view the SQL statements being applied to the target
database.
Applying explicit migrations: [201609302203541_Initial].
Applying explicit migration: 201609302203541_Initial.
Running Seed method.
Puoi vedere i risultati delle attività in SQL Explorer:
Per i comandi Add-Migration
e Update-Database
sono disponibili diverse opzioni che possono essere utilizzate per modificare le attività. Per vedere tutte le opzioni, si prega di utilizzare
get-help Add-Migration
e
get-help Update-Database
Semina dati durante le migrazioni
Dopo aver abilitato e creato le migrazioni potrebbe esserci la necessità di riempire o migrare inizialmente i dati nel database. Esistono diverse possibilità, ma per le migrazioni semplici è possibile utilizzare il metodo 'Seed ()' nel file Configuration creato dopo aver chiamato enable-migrations
.
La funzione Seed()
recupera un contesto di database in quanto è solo un parametro e sei in grado di eseguire operazioni EF all'interno di questa funzione:
protected override void Seed(Model.DatabaseContext context);
Puoi eseguire tutti i tipi di attività all'interno di Seed()
. In caso di errore, viene ripristinata la transazione completa (anche le patch applicate).
Una funzione di esempio che crea dati solo se una tabella è vuota potrebbe avere il seguente aspetto:
protected override void Seed(Model.DatabaseContext context)
{
if (!context.Customers.Any()) {
Customer c = new Customer{ Id = 1, Name = "Demo" };
context.Customers.Add(c);
context.SaveData();
}
}
Una buona funzionalità fornita dagli sviluppatori EF è il metodo di estensione AddOrUpdate()
. Questo metodo consente di aggiornare i dati in base alla chiave primaria o di inserire dati se non esiste già (l'esempio è preso dal codice sorgente generato di Configuration.cs):
protected override void Seed(Model.DatabaseContext context)
{
context.People.AddOrUpdate(
p => p.FullName,
new Person { FullName = "Andrew Peters" },
new Person { FullName = "Brice Lambson" },
new Person { FullName = "Rowan Miller" }
);
}
Tieni presente che
Seed()
viene chiamato dopo l'applicazione dell'ultima patch. Se è necessario eseguire la migrazione o effettuare il seed dei dati durante le patch, è necessario utilizzare altri approcci.
Utilizzo di Sql () durante le migrazioni
Ad esempio: si sta per migrare una colonna esistente da non richiesta a richiesta. In questo caso potrebbe essere necessario riempire alcuni valori predefiniti nella migrazione per le righe in cui i campi modificati sono in realtà NULL
. Nel caso in cui il valore predefinito sia semplice (ad esempio "0") è possibile utilizzare una proprietà default
o defaultSql
nella definizione della colonna. Nel caso non sia così semplice, puoi usare la funzione Sql()
nelle funzioni membro Up()
o Down()
delle tue migrazioni.
Ecco un esempio. Supponendo che un autore di classe contenga un indirizzo email come parte del set di dati. Ora decidiamo di avere l'indirizzo email come campo obbligatorio. Per migrare le colonne esistenti, l'azienda ha l'idea intelligente di creare indirizzi e-mail fittizi come [email protected]
, in cui il nome completo è il nome completo dell'autore senza spazi. Aggiungere l'attributo [Required]
al campo Email
creerebbe la seguente migrazione:
public partial class AuthorsEmailRequired : DbMigration
{
public override void Up()
{
AlterColumn("dbo.Authors", "Email", c => c.String(nullable: false, maxLength: 512));
}
public override void Down()
{
AlterColumn("dbo.Authors", "Email", c => c.String(maxLength: 512));
}
}
Questo fallirebbe nel caso in cui alcuni campi NULL fossero all'interno del database:
Impossibile inserire il valore NULL nella colonna "Email", tabella "App.Model.DatabaseContext.dbo.Authors"; la colonna non consente null. UPDATE fallisce.
Aggiungendo quanto segue come prima il comando AlterColumn
aiuterà:
Sql(@"Update dbo.Authors
set Email = REPLACE(name, ' ', '') + N'@example.com'
where Email is null");
La chiamata al update-database
esito positivo e la tabella è simile a questa (dati di esempio visualizzati):
Altro uso
È possibile utilizzare la funzione Sql()
per tutti i tipi di attività DML e DDL nel proprio database. Viene eseguito come parte della transazione di migrazione; Se l'SQL non riesce, la migrazione completa fallisce e viene eseguito un rollback.
Fare "Update-Database" all'interno del tuo codice
Le applicazioni in esecuzione in ambienti non di sviluppo spesso richiedono aggiornamenti del database. Dopo aver utilizzato il comando Add-Migration
per creare le patch del database, è necessario eseguire gli aggiornamenti su altri ambienti e quindi anche sull'ambiente di test.
Le sfide affrontate comunemente sono:
- nessun Visual Studio installato su ambienti di produzione, e
- nessuna connessione consentita agli ambienti di connessione / cliente nella vita reale.
Una soluzione alternativa è la seguente sequenza di codice che controlla la presenza di aggiornamenti e li esegue in ordine. Si prega di assicurare transazioni corrette e gestione delle eccezioni per garantire che nessun dato venga perso in caso di errori.
void UpdateDatabase(MyDbConfiguration configuration) {
DbMigrator dbMigrator = new DbMigrator( configuration);
if ( dbMigrator.GetPendingMigrations().Any() )
{
// there are pending migrations run the migration job
dbMigrator.Update();
}
}
dove MyDbConfiguration
è la tua configurazione di migrazione da qualche parte nelle tue fonti:
public class MyDbConfiguration : DbMigrationsConfiguration<ApplicationDbContext>
Initial Entity Framework Code Prima migrazione passo dopo passo
- Creare un'applicazione console.
- Installa il pacchetto nuget di EntityFramework eseguendo
Install-Package EntityFramework
in "Console di Gestione pacchetti" - Aggiungi la stringa di connessione nel file app.config, È importante includere
providerName="System.Data.SqlClient"
nella tua connessione. - Crea una classe pubblica come desideri, qualcosa come "
Blog
" - Crea il tuo ContextClass che eredita da DbContext, qualcosa come "
BlogContext
" - Definisci una proprietà nel tuo contesto di tipo DbSet, qualcosa del genere:
public class Blog
{
public int Id { get; set; }
public string Name { get; set; }
}
public class BlogContext: DbContext
{
public BlogContext(): base("name=Your_Connection_Name")
{
}
public virtual DbSet<Blog> Blogs{ get; set; }
}
- È importante passare il nome della connessione nel costruttore (qui Your_Connection_Name)
- In Package Manager Console eseguire il comando
Enable-Migration
, Ciò creerà una cartella di migrazione nel progetto - Esegui comando
Add-Migration Your_Arbitrary_Migraiton_Name
, questo creerà una classe di migrazione nella cartella migrations con due metodi Up () e Down () - Eseguire il comando
Update-Database
per creare un database con una tabella blog