EF Core:come creare un database e una tabella

EF Core:come creare un database e una tabella

In questo articolo, mostrerò come utilizzare EF Core per creare un database con una tabella al suo interno. Alla fine, mostrerò un'app console standalone che inserisce un record in questo database.

Nota:utilizzerò SQL Server. Non l'ho provato con altri fornitori di database. Si prega di lasciare un commento se si utilizza un provider di database diverso e di farmi sapere come è andata.

Aggiungi i pacchetti e gli strumenti nuget di EF Core

Installa i pacchetti nuget EF Core

Il primo passaggio consiste nell'installare i pacchetti nuget di EF Core.

Esecuzione di quanto segue in Package Manager Console (Visualizza> Altre finestre> Package Manager Console).

Install-Package Microsoft.EntityFrameworkCore.SqlServer
Install-Package Microsoft.EntityFrameworkCore.Design
Code language: PowerShell (powershell)

Nota:se non utilizzi SQL Server, dovrai ottenere il pacchetto nuget appropriato per il tuo provider di database.

Questo aggiungerà i riferimenti al pacchetto al tuo file csproj, come questo:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <RootNamespace>ef_core_cli</RootNamespace>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.4">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.4" />
  </ItemGroup>

</Project>

Code language: HTML, XML (xml)

Installa lo strumento dotnet ef

Lo strumento dotnet ef viene utilizzato per installare e aggiornare il database.

Installa lo strumento eseguendo quanto segue sulla riga di comando:

dotnet tool install --global dotnet-ef
Code language: PowerShell (powershell)

Aggiungi un modello

Un modello è una classe che rappresenta una tabella nel database. Ogni proprietà è una colonna nella tabella. Puoi utilizzare gli attributi di annotazione dei dati per definire come deve essere creata ciascuna colonna.

Quando usi EF Core per creare il database, utilizzerà le classi del modello per creare le tabelle.

Ecco il film classe modello. Questo verrà utilizzato per creare i Film tabella.

using System.ComponentModel.DataAnnotations;

public class Movie
{
	[Key]
	public int Id { get; set; }

	[Required]
	[MaxLength(500)]
	public string Name { get; set; }

	[Required]
	public int ReleaseYear { get; set; }

	[Required]
	[MaxLength(500)]
	public string Description { get; set; }

	[Required]
	public int RuntimeMinutes { get; set; }
}
Code language: C# (cs)

Annotazioni dati

Il film il modello utilizza gli attributi di annotazione dei dati per specificare come deve essere creata la tabella. Sono disponibili più annotazioni sui dati, ma spiegherò solo che tre vengono utilizzate nel Film modello:

Annotazione Cosa significa Esempio
Chiave La colonna è la chiave primaria. [Chiave]
public int Id { get; impostare; }

Genera la colonna:
Id (PK, int, non null)
Richiesto La colonna non ammette valori. [Obbligatorio]
public int ReleaseYear { get; impostare; }

Genera la colonna:
ReleaseYear (int, not null)
Lunghezza massima La dimensione del campo della colonna.

Se non lo specifichi, i campi stringa avranno una dimensione del campo MASSIMA.
[Obbligatorio]
[MaxLength(500)]
public string Nome { get; impostare; }

Genera la colonna:
Nome (nvarchar(500), non null)

Aggiungi la tua classe DbContext

Durante la creazione del database, EF Core utilizzerà le informazioni nella classe DbContext per determinare come creare il database.

Quindi la sottoclasse DbContext e:

  • Esegui l'override di OnConfiguring e passa una stringa di connessione.
  • Aggiungi una proprietà DbSet per ogni modello.
using Microsoft.EntityFrameworkCore;

public class StreamingServiceContext : DbContext
{

	private readonly string ConnectionString;
	public StreamingServiceContext(string connectionString)
	{
		ConnectionString = connectionString;
	}
	protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
	{
		optionsBuilder.UseSqlServer(ConnectionString);
	}

	public DbSet<Movie> Movies { get; set; }
}
Code language: C# (cs)

Facoltativo:aggiungi ConnectionString a un file di configurazione

Devi avere la tua stringa di connessione da qualche parte . Mostrerò come aggiungerlo a appsettings.json e quindi sovrascriverlo utilizzando i segreti dell'utente. Questo passaggio è facoltativo, perché puoi scegliere di gestire la stringa di connessione in modo diverso.

Aggiungi appsettings.json

  • Aggiungi un nuovo file chiamato appsettings.json.
  • Impostalo su Copia se più recente .
  • Inserisci la sezione ConnectionStrings. Lo lascio vuoto di proposito. La stringa di connessione effettiva verrà specificata nel file dei segreti utente.
{
  "ConnectionStrings": {
    "Default": "<left blank>"
  }
}
Code language: JSON / JSON with Comments (json)

Il tuo csproj ora dovrebbe assomigliare a questo:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <RootNamespace>ef_core_cli</RootNamespace>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.4">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.4" />
  </ItemGroup>

  <ItemGroup>
    <None Update="appsettings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
  </ItemGroup>

</Project>

Code language: HTML, XML (xml)

Aggiungi i segreti utente e sovrascrivi la stringa di connessione

  • Esegui quanto segue in Package Manager Console (Visualizza> Altre finestre> Package Manager Console).
Install-Package Microsoft.Extensions.Configuration.UserSecrets
Code language: PowerShell (powershell)

Nota:il pacchetto UserSecrets contiene già Microsoft.Extensions.Configuration.Json, quindi non è necessario aggiungerlo separatamente.

  • Fai clic con il pulsante destro del mouse sul progetto> fai clic su Gestisci segreti utente .
  • Questo crea il file secrets.json e lo apre.
  • Ora puoi sovrascrivere la stringa di connessione da appsettings inserendola in secrets.json:
{
  "ConnectionStrings": {
    "Default": "Server=SQL_SERVER_INSTANCE_NAME;Database=StreamingService;Integrated Security=true"
  }
}
Code language: JSON / JSON with Comments (json)

Il tuo file csproj ora dovrebbe contenere le informazioni sui segreti dell'utente:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <RootNamespace>ef_core_cli</RootNamespace>
    <UserSecretsId>9bc52419-f971-411a-91e7-47ecdfb428da</UserSecretsId>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.4">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.4" />
    <PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="5.0.0" />
  </ItemGroup>

  <ItemGroup>
    <None Update="appsettings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
  </ItemGroup>

</Project>

Code language: HTML, XML (xml)

Recupera la stringa di connessione con ConfigurationBuilder

Ora usa ConfigurationBuilder per recuperare la stringa di connessione:

using Microsoft.Extensions.Configuration;

class Program
{
	static void Main(string[] args)
	{
		var config = new ConfigurationBuilder()
			.SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
			.AddJsonFile("appsettings.json")
			.AddUserSecrets<Program>()
			.Build();


		var connectionString = config.GetConnectionString("Default");

		Console.WriteLine(connectionString);
	}
}
Code language: C# (cs)

Esegui il codice. Dovrebbe restituire la stringa di connessione dal file dei segreti dell'utente:

Server=SQL_SERVER_INSTANCE_NAME;Database=StreamingService;Integrated Security=trueCode language: plaintext (plaintext)

Nota:se la stringa di connessione non viene sovrascritta in secrets.json, estrarrà invece la stringa di connessione da appsettings.json.

Crea il database

Ora che hai DbContext, un modello e un modo per ottenere la stringa di connessione, puoi utilizzare dotnet ef per creare effettivamente il database.

Questo è un processo in due fasi. Per prima cosa crei una "migrazione" del database e poi la applichi. Questo avrà più senso quando esegui i passaggi seguenti.

Aggiungi una factory di contesto in fase di progettazione

Quando usi dotnet ef per creare la migrazione, cercherà una classe DbContext senza parametri. Se ciò non esiste, cercherà un'implementazione di IDesignTimeDbContextFactory. Dopodiché, inizia a diventare sempre più complicato.

La soluzione più semplice consiste nell'implementare IDesignTimeDbContextFactory. Questo ti dà il pieno controllo sull'oggetto contesto utilizzato da dotnet ef quando crea le migrazioni.

using Microsoft.EntityFrameworkCore.Design;
using Microsoft.Extensions.Configuration;

public class DesignTimeContextFactory : IDesignTimeDbContextFactory<StreamingServiceContext>
{
	public StreamingServiceContext CreateDbContext(string[] args)
	{
		var config = new ConfigurationBuilder()
			.SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
			.AddJsonFile("appsettings.json")
			.AddUserSecrets<Program>()
			.Build();


		var connectionString = config.GetConnectionString("Default");

		return new StreamingServiceContext(connectionString);
	}
}
Code language: C# (cs)

Crea migrazione database

Per creare una migrazione del database, eseguire il seguente comando (dalla directory del progetto):

dotnet ef migrations add Database_v0
Code language: PowerShell (powershell)

Questo aggiungerà una cartella /Migrazioni/ al tuo progetto e creerà tre file di origine della migrazione:

  • 20210314124406_Database_v0.cs
  • 20210314124406_Database_v0.Designer.cs
  • StreamingServiceContextModelSnapshot.cs

Nota:dotnet ef crea i file di migrazione con un timestamp nel nome.

Questi file di migrazione contengono la logica per la creazione del database. Dai un'occhiata a 20210314124406_Database_v0.cs:

public partial class Database_v0 : Migration
{
	protected override void Up(MigrationBuilder migrationBuilder)
	{
		migrationBuilder.CreateTable(
			name: "Movies",
			columns: table => new
			{
				Id = table.Column<int>(type: "int", nullable: false)
					.Annotation("SqlServer:Identity", "1, 1"),
				Name = table.Column<string>(type: "nvarchar(500)", maxLength: 500, nullable: false),
				ReleaseYear = table.Column<int>(type: "int", nullable: false),
				Description = table.Column<string>(type: "nvarchar(500)", maxLength: 500, nullable: false),
				RuntimeMinutes = table.Column<int>(type: "int", nullable: false)
			},
			constraints: table =>
			{
				table.PrimaryKey("PK_Movies", x => x.Id);
			});
	}

	protected override void Down(MigrationBuilder migrationBuilder)
	{
		migrationBuilder.DropTable(
			name: "Movies");
	}
}
Code language: C# (cs)

Applica la migrazione del database per creare il database

Supponendo che ti trovi in ​​un ambiente di sviluppo, ci sono due opzioni per applicare la migrazione:usa dotnet ef o usa context.Database.Migrate().

Nota:la discussione delle strategie di distribuzione della produzione non rientra nell'ambito di questo articolo.

Opzione 1:applica la migrazione utilizzando dotnet ef

Per applicare l'ultima migrazione, eseguire quanto segue (dalla directory del progetto):

dotnet ef database update
Code language: PowerShell (powershell)

Se il tuo database non esiste, lo creerà, quindi applicherà l'ultima migrazione. Puoi anche specificare quale migrazione utilizzare.

Questa opzione funziona se ti trovi in ​​un ambiente di sviluppo e hai la directory del progetto disponibile.

Opzione 2:applica la migrazione dal codice

Puoi chiamare context.Database.Migrate() e applicherà l'ultima migrazione. Se il tuo database non esiste, lo creerà.

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;

class Program
{
	static void Main(string[] args)
	{
		var config = new ConfigurationBuilder()
			.SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
			.AddJsonFile("appsettings.json")
			.AddUserSecrets<Program>()
			.Build();


		using (var context = new StreamingServiceContext(config.GetConnectionString("Default")))
		{
			context.Database.Migrate();
		}
	}
}
Code language: C# (cs)

Utilizza il database

Ora che hai creato il database, puoi iniziare a usarlo.

Se non hai familiarità con l'utilizzo di EF Core per eseguire query, ti suggerisco di sperimentarlo in un'app console autonoma. Scriverò altri articoli su come utilizzare EF Core, ma per ora, ecco un esempio di inserimento di un record nel database:

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;

class Program
{
	static void Main(string[] args)
	{
		var config = new ConfigurationBuilder()
			.SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
			.AddJsonFile("appsettings.json")
			.AddUserSecrets<Program>()
			.Build();


		using (var context = new StreamingServiceContext(config.GetConnectionString("Default")))
		{
			context.Database.Migrate();

			context.Add(new Movie 
			{ 
			   Name = "John Wick",
			   Description = "A revenge-seeking assassin goes after EVERYONE",
			   ReleaseYear = 2014,
			   RuntimeMinutes = 101
			});
			context.SaveChanges();
		}
	}
}
Code language: C# (cs)

Se guardi nel database, puoi vedere che questo record è stato inserito nella tabella Film.

Codice sorgente in GitHub

Il codice sorgente mostrato in questo articolo è disponibile su GitHub. Se utilizzi il codice di questo repository, assicurati di installare dotnet ef in modo da poter aggiungere/applicare migrazioni.