1×1 des Entity Frameworks
Maurice Jungmann | Softwareentwickler | 23.06.2020
Das Entity Framework | Ein Praxisbeispiel
Sofern mit ASP.NET Core Daten über eine Datenbank verwaltet werden sollen, dann ist das Entity Framework eine gute Wahl, um als Schnittstelle zwischen Datenbank und Anwendung zu dienen. Im Folgenden findet sich eine kurze Anleitung zur Erstellung einer Konsolen Anwendung, die anschließend einfache CRUD Befehle mithilfe des Entity Frameworks ausführen kann.
Projekt erstellen
Zu Beginn wird ein neues „Konsolen-App (.NET Core)“– Projekt erstellt.
Um im Nachhinein Daten in eine Datenbank schreiben zu können ist es notwendig das Nuget-Packet „Microsoft.EntityFrameworkCore.Sqlite“ zu installieren.
Im weiteren Verlauf werden dann die beiden Datenmodell-Klassen „Genre“ und „Book“ angelegt:
Genre CS
using System.Collections.Generic;
namespace EFBasics
{
public class Genre
{
public int Id { get; set; }
public string Title { get; set; }
public List<Book> Books { get; } = new List<Book>();
public override string ToString()
{
return "Genre: " + Id + " - " + Title;
}
}
}
Book CS
namespace EFBasics
{
public class Book
{
public int Id { get; set; }
public string Title { get; set; }
public int GenreId { get; set; }
public Genre Genre { get; set; }
public override string ToString()
{
return "Book: " + Id + " - " + Title;
}
}
}
Nachdem beide Datenmodell-Klassen angelegt sind, müssen diese dem sogenannten Datenbank–Kontext hinzufügt werden. Dafür wird eine neue Klasse namens EFBasicContext benötigt. Unter diesem „Kontext“ werden die beiden Klassen Genre und Book als DbSet zusammengefasst. Um den Datenbank-Kontext einer konkreten Datenbank zuordnen zu können, wird am Ende der Klasse EFBasicContext ein sogenannter ConnectionString angegeben, wie im Folgenden dargestellt:
EFBasicContext.cs
using Microsoft.EntityFrameworkCore;
namespace EFBasics
{
public class EFBasicsContext : DbContext
{
public DbSet<Genre> Genres { get; set; }
public DbSet<Book> Books { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder options)
=> options.UseSqlite("Data Source=efbasics.db");
}
}
Programm-Klasse erstellen
Diese Phase widmet sich der Datenbank-Abfrage. Hierzu wird ein Rahmen innerhalb einer Programm-Klasse benötigt, um zwischen verschiedenen Befehlen auswählen zu können. Für das folgende Beispiel wurde eine while-Schleife verwendet, die solange Durchlaufen wird, bis ein Befehl zum Abbruch des Durchlaufs gegeben wird (Eingabe der 5).
Die bereist erwähnten CRUD Befehle sind anschließend für unterschiedlichste Optionen und Möglichkeiten implementiert worden und können im nachfolgenden Code-Snippet nachvollzogen werden.
CRUD Befehle
Über den Datenbank-Kontext ist es möglich verschiedene Tabellen auszuwählen, die im vorhinein im Datenbank-Kontext implementiert worden sind.
Mit der Funktion Add können neue Einträge in die Tabellen hinzugefügt werden. Mit Hilfe der Funktion Delete können diese problemlos entfernt werden. Besonders wichtig ist es, die Funktion SaveChanges zu verwenden, um sicherzustellen, dass alle Änderungen und Anpassungen gespeichert werden.
Program.cs
class Program
{
static void Main(string[] args)
{
using (var db = new EFBasicsContext())
{
bool done = false;
while (!done)
{
Console.WriteLine("Wählen Sie einen Befehl aus:");
Console.WriteLine("Show all Data (0), Create (1), Read (2), Update (3), Delete (4), Break (5)");
var x = Convert.ToInt32(Console.ReadLine());
switch (x)
{
case 0: //Show Data
{
//Linq with Method Syntax
var myGenresQuery = db.Genres
.Include(c => c.Books)
.AsQueryable();
var myGenres = myGenresQuery.ToList();
foreach (var myGenre in myGenres)
{
Console.WriteLine(myGenre.ToString());
foreach (var myBook in myGenre.Books)
Console.WriteLine("└───" + myBook.ToString());
}
}
break;
case 1: // Create
{
Console.WriteLine("Create");
db.Add(new Genre { Title = "Thriller" });
db.SaveChanges();
}
break;
case 2: // Read
{
Console.WriteLine("Read");
var genre = db.Genres.FirstOrDefault();
Console.WriteLine(genre.ToString());
}
break;
case 3: // Update
{
Console.WriteLine("Update");
var genre = db.Genres.FirstOrDefault();
genre.Title = "Horror";
genre.Books.Add(new Book{ Title = "Shining" });
db.SaveChanges();
}
break;
case 4: // Delete
{
Console.WriteLine("Delete the genre");
var genre = db.Genres.FirstOrDefault();
db.Remove(genre);
db.SaveChanges();
}
break;
case 5:
done = true;
break;
default:
break;
}
}
}
}
}
Exkurs zu Query Syntax vs. Method Syntax in LINQ
Der Unterschied zwischen den beiden Varianten ist lediglich ihre Syntax. Daher ist es für die weitere Programmierung keine Frage der Entscheidung, da mit beiden Varianten gearbeitet werden kann.
Query Syntax vs. Method Syntax in Linq
//Linq with Method Syntax
var book1 = db.Books.SingleOrDefault(p => p.Id == id);
//Linq with Query Syntax
var book2 = (from p in db.Books
where p.Id == id
select p).SingleOrDefault();
Zusammenfassend lässt sch sagen, dass sich die Grundlagen des Entity Frameworks schnell verstehen und erlernen lassen. Jedoch ist nicht auszuschließen, dass es bei der Programmierung auch schnell komplizierter werden kann, insbesondere sobald die Entitäten komplexer oder die Abfragen sehr umfangreich werden. Daher ist es ist immer wichtig zu beachten, wann man sich noch innerhalb eines Datenbank-Kontextes bewegt sowie bei größeren Abfragen Daten nur einmal per Query zu laden.
Potentielle Fehler können schnell entstehen und eine Query doppelt versenden:
var myGenresQuery = db.Genres.AsQueryable();
var myGenres = myGenresQuery.ToList();
var myGenres2 = myGenresQuery.ToList();
Maurice Jungmann | Softwareentwickler | 23.06.2020