Dirk Richter
Software-Entwicklung und Architektur

Code Beispiele für EF, Dapper und ADO? (ORM Teil 3)


Inhaltsverzeichnis

Zusammenfassung

Kurzer Überblick wie der DB-Zugriff über Entity Framework, Dapper und ADO.NET erfolgt. Es fehlt NHibernate/Fluent NHibernate

Beispiel: Benutzung von Entity Framework (EF)

In diesem Beispiel wird gezeigt, wie man mithilfe von Entity Framework (Code-First-Ansatz) eine einfache Datenbank erstellt, Daten einfügt, abruft, aktualisiert und löscht.

Voraussetzungen

  1. Installiere das NuGet-Paket Microsoft.EntityFrameworkCore:
1dotnet add package Microsoft.EntityFrameworkCoredotnet add package Microsoft.EntityFrameworkCore.SqlServer
  1. Erstelle ein neues .NET-Projekt (z. B. Konsole):
1dotnet new console -n EntityFrameworkExamplecd EntityFrameworkExample

Datenbankmodell erstellen

 1// C#: Definiere ein einfaches Modell und den Kontext  
 2using Microsoft.EntityFrameworkCore;  
 3using System;  
 4using System.Collections.Generic;  
 5using System.Linq;  
 6  
 7// Das Datenbankmodell  
 8public class Student  
 9{  
10    public int Id { get; set; }    
11    public string Name { get; set; }    
12    public int Age { get; set; }    
13    public string Course { get; set; }
14}  
15  
16// DbContext: Verbindet die Anwendung mit der Datenbank  
17public class SchoolContext : DbContext  
18{  
19    public DbSet<Student> Students { get; set; }  // Konfiguration der Verbindung zur Datenbank  
20    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)    {        optionsBuilder.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=SchoolDB;Trusted_Connection=True;");    
21  }
22}  

CRUD-Operationen

 1// C#: Führe CRUD-Operationen mit dem Datenmodell durch  
 2class Program  
 3{  
 4    static void Main(string[] args)    {        
 5    using (var context = new SchoolContext())        
 6    {   
 7		// 1. Datenbank erstellen (falls nicht vorhanden)            
 8		context.Database.EnsureCreated();  
 9        // 2. Daten einfügen (Create)            
10        var student = new Student { 
11        Name = "Anna Müller", 
12        Age = 22, 
13        Course = "Informatik" };            
14        context.Students.Add(student);            
15        context.SaveChanges(); // Änderungen speichern      
16        Console.WriteLine("Student hinzugefügt.");  
17  
18        // 3. Daten abrufen (Read)            
19        var students = context.Students.ToList();  
20        Console.WriteLine("Alle Studenten in der Datenbank:"); 
21        foreach (var s in students)            
22        {                
23	        Console.WriteLine($"ID: {s.Id}, Name: {s.Name}, Alter: {s.Age}, Kurs: {s.Course}");           
24        }  
25        // 4. Daten aktualisieren (Update)            
26        var existingStudent = context.Students.FirstOrDefault(s => s.Name == "Anna Müller");            
27        if (existingStudent != null)            
28        {                
29	        existingStudent.Age = 23;                
30	        context.SaveChanges();                
31	        Console.WriteLine($"Student {existingStudent.Name} aktualisiert.");    
32        }  
33        // 5. Daten löschen (Delete)            
34        var studentToDelete = context.Students.FirstOrDefault(s => s.Name == "Anna Müller");            
35        if (studentToDelete != null)            
36        {
37	        context.Students.Remove(studentToDelete);                
38            context.SaveChanges();                
39	            Console.WriteLine($"Student {studentToDelete.Name} gelöscht.");            }        
40	}    
41}             

Erklärung der Schritte

  1. Modelle erstellen: Die Student-Klasse definiert die Struktur der Datenbank.
  2. DbContext: Die SchoolContext-Klasse verbindet die Anwendung mit der Datenbank und definiert den Students-Table.
  3. Create: Neue Daten werden mit Add() hinzugefügt und mit SaveChanges() gespeichert.
  4. Read: Abfragen von Daten erfolgt mit LINQ (context.Students.ToList()).
  5. Update: Daten können durch das Bearbeiten des gefundenen Objekts und erneutes Speichern (SaveChanges()) aktualisiert werden.
  6. Delete: Mit Remove() können Objekte aus der Datenbank gelöscht werden.

Erwartetes Ergebnis

Nach dem Ausführen der Anwendung geschieht Folgendes:

  1. Ein neuer Student namens “Anna Müller” wird in die Datenbank eingefügt.
  2. Die Liste der Studenten wird angezeigt.
  3. Der Datensatz von “Anna Müller” wird aktualisiert (Alter von 22 auf 23 Jahre).
  4. Der aktualisierte Datensatz wird aus der Datenbank gelöscht.

Wichtige Hinweise

Fazit

Entity Framework (EF) erleichtert die Arbeit mit Datenbanken enorm und ist ideal für Einsteiger. Die Kombination aus automatischem Mapping, LINQ und Integration mit .NET-Tools macht es zu einer großartigen Wahl für einfache Datenbanken.

Beispiel: Benutzung von Dapper

Dieses Beispiel zeigt, wie man Dapper für die Arbeit mit einer einfachen SQL-Datenbank verwendet. Im Gegensatz zu Entity Framework verwendet Dapper direkt SQL-Abfragen und ist ideal für Entwickler, die den SQL-Zugriff vollständig kontrollieren möchten.

Voraussetzungen

  1. Installiere das NuGet-Paket Dapper:
1dotnet add package Dapperdotnet add package Microsoft.Data.SqlClient
  1. Erstelle ein neues .NET-Projekt (z. B. Konsole):
1dotnet new console -n DapperExamplecd DapperExample

Datenbankmodell erstellen

1// C#: Definiere das Datenmodell  
2public class Student  
3{  
4    public int Id { get; set; }    
5    public string Name { get; set; }    
6    public int Age { get; set; }    
7    public string Course { get; set; }
8}  

CRUD-Operationen mit Dapper

 1// C#: CRUD-Operationen mit Dapper  
 2using System.Data;
 3
 4internal class Program
 5{
 6    private static void Main(string[] args)
 7    {
 8        // Verbindungszeichenfolge zur Datenbank (lokale SQL-Instanz)        
 9        var connectionString = "Server=(localdb)\\mssqllocaldb;Database=SchoolDB;Trusted_Connection=True;";
10        using (IDbConnection dbConnection = new SqlConnection(connectionString))
11        {
12            // 1. Erstelle die Datenbank (falls noch nicht vorhanden)    
13            dbConnection.Open();
14            var createTableQuery = @"
15            IF NOT EXISTS (                  
16            SELECT * FROM sysobjects WHERE name='Students' AND xtype='U')
17            CREATE TABLE Students (                    
18            Id INT PRIMARY KEY IDENTITY(1,1),                    
19            Name NVARCHAR(50),                    
20            Age INT,                    
21            Course NVARCHAR(50)                
22            )";
23            dbConnection.Execute(createTableQuery);
24
25            // 2. Daten einfügen (Create)            
26            var insertQuery = "INSERT INTO Students (Name, Age, Course) VALUES(Name, Age, Course)";            
27            var newStudent = new Student
28            {
29                Name = "Anna Müller",
30                Age = 22,
31                Course = "Informatik"
32            };
33            dbConnection.Execute(insertQuery, newStudent);
34            Console.WriteLine("Student hinzugefügt.");
35            // 3. Daten abrufen (Read)            
36            var selectQuery = "SELECT * FROM Students";
37            IEnumerable<Student> students = dbConnection.Query<Student>(selectQuery);
38            Console.WriteLine("Alle Studenten in der Datenbank:");
39            foreach (var student in students)
40                Console.WriteLine(
41                    $"ID: {student.Id}, Name: {student.Name}, Alter: {student.Age}, Kurs: {student.Course}");
42            // 4. Daten aktualisieren (Update)            
43            var updateQuery = "UPDATE Students SET Age = @Age WHERE Name = @Name";
44            dbConnection.Execute(
45                updateQuery, new { Age = 23, Name = "Anna Müller" });
46            Console.WriteLine("Student aktualisiert.");
47
48            // 5. Daten löschen (Delete)            
49            var deleteQuery = "DELETE FROM Students WHERE Name = @Name";
50            dbConnection.Execute(deleteQuery, new { Name = "Anna Müller" });
51            Console.WriteLine("Student gelöscht.");
52        }
53    }
54}

Erklärung der Schritte

  1. SQL-Verbindung: Mit SqlConnection wird eine Verbindung zur Datenbank hergestellt. Die verbindungsspezifischen Methoden stammen aus System.Data.
  2. Tabelle erstellen: Die Abfrage CREATE TABLE wird nur ausgeführt, wenn die Tabelle noch nicht existiert.
  3. Daten einfügen: Die Methode Execute wird verwendet, um SQL-Befehle wie INSERT auszuführen. Parameter (@Name, @Age) verhindern SQL-Injection.
  4. Daten abrufen: Mit Query<T>() lassen sich Abfragen ausführen und die Ergebnisse in einer Liste von Objekten speichern.
  5. Daten aktualisieren: Mithilfe der Execute-Methode wird eine UPDATE-Anweisung ausgeführt.
  6. Daten löschen: Auch DELETE-Anfragen werden mit Execute ausgeführt.

Vorteile von Dapper im Beispiel

Wichtige Hinweise

Fazit

Dapper ist ideal für Entwickler, die vollständige SQL-Kontrolle benötigen und hohe Performance erwarten. Es erfordert etwas mehr Wissen über SQL und den Umgang mit Datenbanken, ermöglicht jedoch maximale Effizienz bei einfachen und schnellen Datenbankoperationen.

Beispiel: Reine ADO.NET Implementierung

Dieses Beispiel zeigt, wie CRUD-Operationen (Create, Read, Update, Delete) mit ADO.NET in einer einfachen SQL-Datenbank implementiert werden.

Voraussetzungen

  1. Installiere das NuGet-Paket Microsoft.Data.SqlClient (falls noch nicht verfügbar):
1dotnet add package Microsoft.Data.SqlClient
  1. Erstelle ein neues .NET-Projekt (z. B. Konsole):
1dotnet new console -n AdoNetExamplecd AdoNetExample

CRUD-Operationen mit ADO.NET

 1internal class Program
 2{
 3    private static void Main(string[] args)
 4    {
 5        // Verbindungszeichenfolge        
 6        var connectionString = "Server=(localdb)\\mssqllocaldb;Database=SchoolDB;Trusted_Connection=True;";
 7        // 1. Tabelle erstellen (falls nicht vorhanden)        
 8        using (var connection = new SqlConnection(connectionString))
 9        {
10            connection.Open();
11            var createTableQuery = @"                
12        IF NOT EXISTS (                  
13        SELECT * FROM sysobjects WHERE name='Students' AND xtype='U'    
14        )                
15        CREATE TABLE Students (                    
16        Id INT PRIMARY KEY IDENTITY(1,1),                    
17        Name NVARCHAR(50),                    
18        Age INT,                    
19        Course NVARCHAR(50)                
20        )";
21            using (var command = new SqlCommand(createTableQuery, connection))
22
23            {
24                command.ExecuteNonQuery();
25                Console.WriteLine("Tabelle 'Students' erstellt oder bereits vorhanden.");
26            }
27        }
28        // CRUD-Operationen:  
29
30        // 2. Daten einfügen (Create)        
31        using (var connection = new SqlConnection(connectionString))
32        {
33            connection.Open();
34            var insertQuery = "INSERT INTO Students (Name, Age, Course) VALUES (@Name, @Age, @Course)";
35            using (var command = new SqlCommand(insertQuery, connection))
36            {
37                command.Parameters.AddWithValue("@Name", "Anna Müller");
38                command.Parameters.AddWithValue("@Age", 22);
39                command.Parameters.AddWithValue("@Course", "Informatik");
40                int rowsAffected = command.ExecuteNonQuery();
41                Console.WriteLine($"{rowsAffected} Zeile(n) eingefügt.");
42            }
43        }
44
45        // 3. Daten abrufen (Read)        
46        using (var connection = new SqlConnection(connectionString))
47        {
48            connection.Open();
49            var selectQuery = "SELECT * FROM Students";
50            using (var command = new SqlCommand(selectQuery, connection))
51            {
52                using (var reader = command.ExecuteReader())
53                {
54                    Console.WriteLine("Alle Studenten in der Datenbank:");
55                    while (reader.Read())
56                        Console.WriteLine(
57                            $"ID: {reader["Id"]}, Name: {reader["Name"]}, Alter: {reader["Age"]}, Kurs: {reader["Course"]}");
58                }
59            }
60        }
61
62        // 4. Daten aktualisieren (Update)        
63        using (var connection = new SqlConnection(connectionString))
64        {
65            connection.Open();
66            var updateQuery = "UPDATE Students SET Age = @Age WHERE Name = @Name";
67            using (var command = new SqlCommand(updateQuery, connection))
68            {
69                command.Parameters.AddWithValue("@Age", 23);
70                command.Parameters.AddWithValue("@Name", "Anna Müller");
71                int rowsAffected = command.ExecuteNonQuery();
72                Console.WriteLine($"{rowsAffected} Zeile(n) aktualisiert.");
73            }
74        }
75
76        // 5. Daten löschen (Delete)        
77        using (var connection = new SqlConnection(connectionString))
78        {
79            connection.Open();
80            var deleteQuery = "DELETE FROM Students WHERE Name = @Name";
81            using (var command = new SqlCommand(deleteQuery, connection))
82            {
83                command.Parameters.AddWithValue("@Name", "Anna Müller");
84                int rowsAffected = command.ExecuteNonQuery();
85                Console.WriteLine($"{rowsAffected} Zeile(n) gelöscht.");
86            }
87        }
88    }
89}

Erklärung der Schritte

  1. Verbindungsaufbau: Alle SQL-Operationen erfolgen über die SqlConnection-Klasse, die die Verbindung zur Datenbank bereitstellt.
  2. SQL-Befehle ausführen: SQL-Befehle werden mit der SqlCommand-Klasse ausgeführt. Dies umfasst INSERT, SELECT, UPDATE und DELETE.
  3. Parameter verwenden: SQL-Parameter (@Name, @Age) in SqlCommand verhindern SQL-Injection und bieten Sicherheit.
  4. Daten lesen:
  1. Speicherverwaltung: using-Blöcke werden verwendet, um Datenbankressourcen automatisch freizugeben.

Vorteile von ADO.NET

Nachteile von ADO.NET

Fazit

ADO.NET bietet maximale Kontrolle über Datenbankoperationen, ist aber im Vergleich zu Frameworks wie Entity Framework oder Dapper zeitintensiver in der Entwicklung und erfordert mehr Kenntnisse im Umgang mit SQL und Datenbankmanagement. Es eignet sich am besten für Entwickler, die direkt auf die niedrigste Ebene des Datenbankzugriffs zugreifen oder keine zusätzlichen Bibliotheken verwenden wollen.

#Entityframework #Dapper #Database