Dela via


Koda först till en ny databas

Den här videon och den stegvisa genomgången ger en introduktion till Code First-utveckling som riktar sig mot en ny databas. I det här scenariot ingår att rikta in sig på en databas som inte finns och som Code First kommer att skapa, eller på en tom databas där Code First kommer att lägga till nya tabeller. Med Code First kan du definiera din modell med hjälp av C# eller VB.Net klasser. Ytterligare konfiguration kan eventuellt utföras med hjälp av attribut på dina klasser och egenskaper eller med hjälp av ett fluent-API.

Titta på videon

Den här videon ger en introduktion till Code First-utveckling som riktar sig mot en ny databas. I det här scenariot ingår målinriktning av en databas som inte finns och som Code First skapar, eller en tom databas som Code First lägger till nya tabeller i. Med Code First kan du definiera din modell med hjälp av C# eller VB.Net klasser. Ytterligare konfiguration kan eventuellt utföras med hjälp av attribut på dina klasser och egenskaper eller med hjälp av ett fluent-API.

Presenterad av: Rowan Miller

Video: WMV | MP4 | WMV (ZIP)

Förutsättningar

Du måste ha minst Visual Studio 2010 eller Visual Studio 2012 installerat för att slutföra den här genomgången.

Om du använder Visual Studio 2010 måste du också ha NuGet installerat.

1. Skapa programmet

För att hålla det enkelt ska vi skapa ett grundläggande konsolprogram som använder Code First för att utföra dataåtkomst.

  • Öppna Visual Studio
  • Fil –> Ny –> Projekt...
  • Välj Windows på den vänstra menyn och Konsolprogram
  • Ange CodeFirstNewDatabaseSample som namn
  • Välj OK

2. Skapa modellen

Nu ska vi definiera en mycket enkel modell med hjälp av klasser. Vi definierar dem bara i den Program.cs filen, men i ett verkligt program delar du upp dina klasser i separata filer och potentiellt ett separat projekt.

Under klassdefinitionen Program i Program.cs lägg till följande två klasser.

public class Blog
{
    public int BlogId { get; set; }
    public string Name { get; set; }

    public virtual List<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public int BlogId { get; set; }
    public virtual Blog Blog { get; set; }
}

Du kommer att märka att vi gör de två navigeringsegenskaperna (Blog.Posts och Post.Blog) virtuella. Detta aktiverar funktionen Lazy Loading i Entity Framework. Lazy Loading innebär att innehållet i dessa egenskaper läses in automatiskt från databasen när du försöker komma åt dem.

3. Skapa en kontext

Nu är det dags att definiera en härledd kontext som representerar en session med databasen, så att vi kan fråga efter och spara data. Vi definierar en kontext som härleds från System.Data.Entity.DbContext och exponerar en typbeskriven DbSet<TEntity> för varje klass i vår modell.

Nu börjar vi använda typer från Entity Framework, så vi måste lägga till EntityFramework NuGet-paketet.

  • Project –> Hantera NuGet-paket... Obs! Om du inte har alternativet Hantera NuGet-paket... bör du installera den senaste versionen av NuGet
  • Välj fliken Online
  • Välj EntityFramework-paketet
  • Klicka på Installera

Lägg till en using-instruktion för System.Data.Entity överst i Program.cs.

using System.Data.Entity;

Lägg till följande härledda kontext under klassen Post i Program.cs.

public class BloggingContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }
}

Här är en fullständig lista över vad Program.cs nu ska innehålla.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Entity;

namespace CodeFirstNewDatabaseSample
{
    class Program
    {
        static void Main(string[] args)
        {
        }
    }

    public class Blog
    {
        public int BlogId { get; set; }
        public string Name { get; set; }

        public virtual List<Post> Posts { get; set; }
    }

    public class Post
    {
        public int PostId { get; set; }
        public string Title { get; set; }
        public string Content { get; set; }

        public int BlogId { get; set; }
        public virtual Blog Blog { get; set; }
    }

    public class BloggingContext : DbContext
    {
        public DbSet<Blog> Blogs { get; set; }
        public DbSet<Post> Posts { get; set; }
    }
}

Det är all kod vi behöver för att börja lagra och hämta data. Uppenbarligen pågår det en hel del bakom kulisserna och vi tar en titt på det om ett ögonblick men först ska vi se det i aktion.

4. Läsa och skriva data

Implementera main-metoden i Program.cs enligt nedan. Den här koden skapar en ny instans av kontexten och använder den sedan för att infoga en ny blogg. Sedan använder den en LINQ-fråga för att hämta alla bloggar från databasen som ordnas alfabetiskt efter Rubrik.

class Program
{
    static void Main(string[] args)
    {
        using (var db = new BloggingContext())
        {
            // Create and save a new Blog
            Console.Write("Enter a name for a new Blog: ");
            var name = Console.ReadLine();

            var blog = new Blog { Name = name };
            db.Blogs.Add(blog);
            db.SaveChanges();

            // Display all Blogs from the database
            var query = from b in db.Blogs
                        orderby b.Name
                        select b;

            Console.WriteLine("All blogs in the database:");
            foreach (var item in query)
            {
                Console.WriteLine(item.Name);
            }

            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
        }
    }
}

Nu kan du köra programmet och testa det.

Enter a name for a new Blog: ADO.NET Blog
All blogs in the database:
ADO.NET Blog
Press any key to exit...

Var är mina data?

Enligt konventionen har DbContext skapat en databas åt dig.

  • Om en lokal SQL Express-instans är tillgänglig (installeras som standard med Visual Studio 2010) har Code First skapat databasen på den instansen
  • Om SQL Express inte är tillgängligt försöker Code First använda LocalDB (installeras som standard med Visual Studio 2012)
  • Databasen har fått sitt namn efter det fullständigt kvalificerade namnet på den härledda kontexten, i vårt fall CodeFirstNewDatabaseSample.BloggingContext

Det här är bara standardkonventionerna och det finns olika sätt att ändra databasen som Code First använder. Mer information finns i avsnittet Hur DbContext identifierar modellen och databasanslutningen . Du kan ansluta till den här databasen med Hjälp av Server Explorer i Visual Studio

  • Visa –> ServerUtforskaren

  • Högerklicka på Dataanslutningar och välj Lägg till anslutning...

  • Om du inte har anslutit till en databas från Server Explorer innan du måste välja Microsoft SQL Server som datakälla

    Välj datakälla

  • Anslut till antingen LocalDB eller SQL Express, beroende på vilken du har installerat

Nu kan vi granska schemat som Code First skapade.

Schema initialt

DbContext räknade ut vilka klasser som ska inkluderas i modellen genom att titta på de DbSet-egenskaper som vi definierade. Sedan används standarduppsättningen med Code First-konventioner för att fastställa tabell- och kolumnnamn, fastställa datatyper, hitta primära nycklar osv. Senare i den här genomgången tittar vi på hur du kan åsidosätta dessa konventioner.

5. Hantera modelländringar

Nu är det dags att göra vissa ändringar i vår modell, när vi gör dessa ändringar måste vi också uppdatera databasschemat. För att göra detta kommer vi att använda en funktion som kallas Code First Migrations eller Migreringar för kort.

Med migreringar kan vi ha en ordnad uppsättning steg som beskriver hur du uppgraderar (och nedgraderar) vårt databasschema. Vart och ett av dessa steg, som kallas migrering, innehåller kod som beskriver de ändringar som ska tillämpas. 

Det första steget är att aktivera Code First Migrations för vår BloggingContext.

  • Verktyg –> Bibliotekspakethanteraren –> Package Manager-konsolen

  • Kör kommandot Enable-Migrations i Package Manager Console

  • En ny migreringsmapp har lagts till i vårt projekt som innehåller två objekt:

    • Configuration.cs – Den här filen innehåller de inställningar som migreringar ska använda för migrering av BloggingContext. Vi behöver inte ändra något för den här genomgången, men här kan du ange startdata, registrera providers för andra databaser, ändra namnområdet som migreringar genereras i osv.
    • <timestamp>_InitialCreate.cs – Det här är din första migrering, det representerar de ändringar som redan har tillämpats på databasen för att ta den från att vara en tom databas till en som innehåller tabellerna Bloggar och inlägg. Vi låter Code First automatiskt skapa dessa tabeller åt oss, men nu när vi har valt migreringar har de konverterats till en migrering. Code First har också registrerat i vår lokala databas att den här migreringen redan har tillämpats. Tidsstämpeln på filnamnet används i beställningssyfte.

    Nu ska vi göra en ändring i vår modell, lägga till en URL-egenskap i klassen Blogg:

public class Blog
{
    public int BlogId { get; set; }
    public string Name { get; set; }
    public string Url { get; set; }

    public virtual List<Post> Posts { get; set; }
}
  • Kör kommandot Add-Migration AddUrl i Package Manager Console. Kommandot Add-Migration söker efter ändringar sedan din senaste migrering och skapar en ny migrering med eventuella ändringar som hittas. Vi kan ge migreringar ett namn. i det här fallet anropar vi migreringen "AddUrl". Den genererade koden säger att vi måste lägga till en kolumn för URL, som kan innehålla strängdata, till dbo.Bloggtabell. Om det behövs kan vi redigera den genererade koden, men det krävs inte i det här fallet.
namespace CodeFirstNewDatabaseSample.Migrations
{
    using System;
    using System.Data.Entity.Migrations;

    public partial class AddUrl : DbMigration
    {
        public override void Up()
        {
            AddColumn("dbo.Blogs", "Url", c => c.String());
        }

        public override void Down()
        {
            DropColumn("dbo.Blogs", "Url");
        }
    }
}
  • Kör kommandot Update-Database i Package Manager Console. Det här kommandot tillämpar eventuella väntande migreringar på databasen. Vår InitialCreate-migrering har redan tillämpats så migreringar tillämpar bara vår nya AddUrl-migrering. Tips: Du kan använda växeln –Verbose när du anropar Update-Database för att se SQL som utförs mot databasen.

Den nya URL-kolumnen läggs nu till i tabellen Bloggar i databasen:

Schema med URL

6. Dataanteckningar

Hittills har vi bara låtit EF identifiera modellen med sina standardkonventioner, men det kommer att finnas tillfällen då våra klasser inte följer konventionerna och vi måste kunna utföra ytterligare konfiguration. Det finns två alternativ för detta. Vi tittar på Dataanteckningar i det här avsnittet och sedan api:et fluent i nästa avsnitt.

  • Nu ska vi lägga till en användarklass i vår modell
public class User
{
    public string Username { get; set; }
    public string DisplayName { get; set; }
}
  • Vi behöver också lägga till en uppsättning i vår härledda kontext
public class BloggingContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }
    public DbSet<User> Users { get; set; }
}
  • Om vi försökte lägga till en migrering får vi ett felmeddelande om att "EntityType "Användare" inte har någon definierad nyckel. Definiera nyckeln för den här EntityType." eftersom EF inte har något sätt att veta att Användarnamn ska vara den primära nyckeln för användaren.
  • Vi ska använda dataanteckningar nu, så vi måste lägga till en using-instruktion överst i Program.cs
using System.ComponentModel.DataAnnotations;
  • Kommentera nu egenskapen Användarnamn för att identifiera att det är den primära nyckeln
public class User
{
    [Key]
    public string Username { get; set; }
    public string DisplayName { get; set; }
}
  • Använd kommandot Add-Migration AddUser för att skapa en migrering för att tillämpa dessa ändringar på databasen
  • Kör kommandot Update-Database för att tillämpa den nya migreringen på databasen

Den nya tabellen läggs nu till i databasen:

Schema med användare

Den fullständiga listan över anteckningar som stöds av EF är:

7. Fluent API

I föregående avsnitt tittade vi på att använda dataanteckningar för att komplettera eller åsidosätta vad som identifierades av konventionen. Det andra sättet att konfigurera modellen är via API:et Code First fluent.

De flesta modellkonfigurationer kan göras med enkla dataanteckningar. API:et fluent är ett mer avancerat sätt att ange modellkonfiguration som omfattar allt som dataanteckningar kan göra utöver en mer avancerad konfiguration som inte är möjlig med dataanteckningar. Dataanteckningar och fluent-API:et kan användas tillsammans.

För att få åtkomst till fluent-API:et åsidosätter du metoden OnModelCreating i DbContext. Låt oss säga att vi ville byta namn på kolumnen som User.DisplayName lagras i till display_name.

  • Åsidosätt metoden OnModelCreating på BloggingContext med följande kod
public class BloggingContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }
    public DbSet<User> Users { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>()
            .Property(u => u.DisplayName)
            .HasColumnName("display_name");
    }
}
  • Använd kommandot Add-Migration ChangeDisplayName för att skapa en migrering för att tillämpa dessa ändringar på databasen.
  • Kör kommandot Update-Database för att tillämpa den nya migreringen på databasen.

Kolumnen DisplayName har nu bytt namn till display_name:

Schema med omdöpt visningsnamn

Sammanfattning

I den här genomgången tittade vi på Code First-utveckling med hjälp av en ny databas. Vi definierade en modell med hjälp av klasser som sedan använde den modellen för att skapa en databas och lagra och hämta data. När databasen skapades använde vi Code First Migrations för att ändra schemat när vår modell utvecklades. Vi såg också hur du konfigurerar en modell med hjälp av dataanteckningar och Fluent API.