C# Datenbank verbinden: ADO.NET & Entity Framework einfach erklärt
So greifst du aus C# auf Datenbanken zu: mit ADO.NET für direktes SQL oder EF Core als modernem ORM – beide Wege mit Beispielen erklärt.
Von Marcel Schmidtpeter 07. Okt. 2026 Stell dir vor, du bekommst dein erstes richtiges Projekt: eine kleine Verwaltungsapp, die Kunden, Tickets oder Noten speichern muss. Spätestens dann führt kein Weg an einer Datenbank vorbei. Ob du als Fachinformatiker-Azubi dein Abschlussprojekt planst, im Studium eine Anwendung programmieren sollst oder im ersten Job Legacy-Code warten darfst - Datenbankzugriff aus C# heraus gehört zum Grundhandwerk.
In C# gibt es dafür zwei Standard-Wege: ADO.NET für direkten SQL-Zugriff und Entity Framework Core als komfortable Objekt-Schicht. Hier lernst du beide - mit vollständigem Code, den du direkt nachbauen kannst.
Was brauchst du für den Start?
Für beide Wege brauchst du dieselbe Grundausstattung. Check diese drei Punkte:
.NET SDK (ab Version 6) und ein Editor wie Visual Studio oder VS Code
Grundlagen in C#: Klassen, Properties, Methoden - mehr nicht
Eine SQLite-Datenbankdatei. Warum SQLite? Weil sie kein eigenes Installationsprogramm und keinen Server braucht. Die Datenbank ist einfach eine Datei auf deiner Festplatte - perfekt zum Lernen und für Ausbildungsprojekte.
Für die Codebeispiele brauchst du zwei NuGet-Pakete: `Microsoft.Data.Sqlite` und `Microsoft.EntityFrameworkCore.Sqlite`. Wie du Pakete installierst, zeigen wir in unserem Tutorial zur dotnet CLI und NuGet.
Was ist ADO.NET?
ADO.NET ist die eingebaute Datenzugriffsschicht von .NET. Sie stellt Klassen für Verbindungen, Befehle und Lesezugriffe bereit, mit denen du SQL direkt an die Datenbank schickst. Du schreibst also selbst das SQL und behältst volle Kontrolle. Die offizielle Referenz findest du bei Microsoft Learn.
Merke: ADO.NET ist die Basis des Datenzugriffs in .NET. Entity Framework nutzt im Hintergrund dieselben Mechanismen - wer ADO.NET versteht, versteht auch, was EF für ihn erledigt.
Schritt 1: Verbindung aufbauen
Jeder Datenbankkontakt beginnt mit einer Verbindung. Die nötigen Infos stehen im Connection String - einem Text, der z. B. sagt, welche Datei oder welcher Server genutzt wird:
using Microsoft.Data.Sqlite;
// Verbindung zur SQLite-Datei herstellen
using var connection = new SqliteConnection("Data Source=schulapp.db");
connection.Open();Das `using` sorgt dafür, dass die Verbindung nach dem Block automatisch geschlossen wird. Wie das genau funktioniert, erklären wir im Artikel zu using und IDisposable. Warum das wichtig ist? Offene Verbindungen blockieren Ressourcen - bei SQLite die Datei, bei echten Datenbankservern sogar begrenzte Verbindungsslots.
Schritt 2: Tabelle anlegen und Daten schreiben
Für Befehle ohne Rückgabe (wie `CREATE` oder `INSERT`) nutzt du `ExecuteNonQuery`. Und ganz wichtig: Werte kommen niemals per String-Verkettung ins SQL, sondern immer über Parameter:
// Tabelle anlegen
using var createCmd = connection.CreateCommand();
createCmd.CommandText = @"
CREATE TABLE IF NOT EXISTS Schueler (
Id INTEGER PRIMARY KEY AUTOINCREMENT,
Name TEXT NOT NULL,
Jahrgang INTEGER NOT NULL
)";
createCmd.ExecuteNonQuery();
// FALSCH: Tuer offen fuer SQL-Injection
// cmd.CommandText = $"INSERT INTO Schueler (Name) VALUES ('{eingabe}')";
// RICHTIG: Werte als Parameter uebergeben
using var insertCmd = connection.CreateCommand();
insertCmd.CommandText =
"INSERT INTO Schueler (Name, Jahrgang) VALUES ($name, $jahrgang)";
insertCmd.Parameters.AddWithValue("$name", "Anna Schmidt");
insertCmd.Parameters.AddWithValue("$jahrgang", 2026);
insertCmd.ExecuteNonQuery();SQL-Injection bedeutet: Jemand schreibt bösartigen SQL-Code in ein Eingabefeld, und dein zusammengeklebter String führt ihn aus. In IHK-Prüfungen und Vorstellungsgesprächen eine garantierte Fangfrage - Parameter sind die einzige richtige Antwort.
Schritt 3: Daten lesen mit dem DataReader
Zum Lesen nutzt du `ExecuteReader`. Der DataReader liefert Zeile für Zeile, solange du mit `Read()` weiterblätterst:
using var selectCmd = connection.CreateCommand();
selectCmd.CommandText = "SELECT Id, Name, Jahrgang FROM Schueler";
using var reader = selectCmd.ExecuteReader();
while (reader.Read())
{
Console.WriteLine(
$"{reader.GetInt32(0)}: {reader.GetString(1)} (Jahrgang {reader.GetInt32(2)})");
}Damit hast du den kompletten Kreislauf: verbinden, schreiben, lesen. Genau so steht es auch in vielen IHK-Aufgaben.
Was ist Entity Framework Core?
Entity Framework Core (EF Core) ist ein ORM - ein Object-Relational Mapper. Das heißt: Statt SQL zu schreiben, arbeitest du mit normalen C#-Klassen. EF übersetzt deine Objektoperationen automatisch in SQL-Befehle. Stell dir EF wie einen Übersetzer vor: Du redest C#, er redet Datenbank. Details liefert die offizielle EF-Core-Dokumentation.
Schritt 1: Modell und DbContext definieren
Du brauchst zwei Dinge: eine Modellklasse (die später eine Tabelle wird) und einen DbContext - die zentrale Klasse, die die Brücke zwischen deinem Code und der Datenbank schlägt:
using Microsoft.EntityFrameworkCore;
// Eine Klasse = eine Tabelle
public class Schueler
{
public int Id { get; set; }
public string Name { get; set; } = "";
public int Jahrgang { get; set; }
}
// Der DbContext verwaltet alle Tabellen
public class SchulContext : DbContext
{
public DbSet<Schueler> Schueler => Set<Schueler>();
protected override void OnConfiguring(DbContextOptionsBuilder options)
=> options.UseSqlite("Data Source=schulapp.db");
}Ein DbSet entspricht dabei einer Tabelle - `context.Schueler` verhält sich wie eine Liste von `Schueler`-Objekten.
Schritt 2: Speichern und abfragen
Schreiben heißt: Objekt ins `DbSet` legen und `SaveChanges` aufrufen. Lesen läuft über LINQ, die Abfragesprache von C#:
using var context = new SchulContext();
context.Database.EnsureCreated();
// Schreiben
context.Schueler.Add(new Schueler { Name = "Ben Meyer", Jahrgang = 2025 });
context.SaveChanges();
// Lesen
var treffer = context.Schueler
.Where(s => s.Jahrgang >= 2025)
.OrderBy(s => s.Name)
.ToList();Kein einziger SQL-String - EF erzeugt die Befehle im Hintergrund. Wie LINQ-Filter im Detail funktionieren, zeigen wir im Artikel zu LINQ filtern und transformieren.
ADO.NET oder Entity Framework: Was wann?
Die Kurzfassung: ADO.NET gibt dir maximale Kontrolle und ist prüfungsrelevant, EF Core spart dir im Alltag Zeit. Hier der Vergleich im Detail:
Kriterium | ADO.NET | Entity Framework Core |
Abstraktion | Niedrig - du schreibst SQL | Hoch - du arbeitest mit Objekten |
Einstiegshürde | Klein, wenn du SQL kennst | Mehr Konzepte (DbContext, Migrations) |
Kontrolle | Voll - jeder Befehl ist deiner | Generiertes SQL, teils mit Überraschungen |
Code-Menge | Mehr Boilerplate | Kompakt, wenig Wiederholung |
Typischer Einsatz | Skripte, Reports, Leistungskritisches | Geschäftsanwendungen, CRUD-Apps |
Merke: Es ist kein Entweder-oder. In der Praxis kennst du beide - ADO.NET als Fundament, EF Core als Werkzeug für den Alltag.
Für die Abschlussprüfung gilt fast immer: ADO.NET mit SQL gehört zum Pflichtrepertoire. Im ersten Job wirst du dagegen sehr oft auf EF Core treffen, weil es Entwicklungszeit spart.
Vollständiges Beispiel: Lauffähige Konsole-App
Alle Teile zusammen ergeben dieses Programm. Leg eine neue Konsole an, installiere `Microsoft.EntityFrameworkCore.Sqlite` und füge den Code ein:
using Microsoft.EntityFrameworkCore;
public class Schueler
{
public int Id { get; set; }
public string Name { get; set; } = "";
public int Jahrgang { get; set; }
}
public class SchulContext : DbContext
{
public DbSet<Schueler> Schueler => Set<Schueler>();
protected override void OnConfiguring(DbContextOptionsBuilder options)
=> options.UseSqlite("Data Source=schulapp.db");
}
public class Program
{
public static void Main()
{
using var context = new SchulContext();
context.Database.EnsureCreated();
// Zwei Datensaetze speichern
context.Schueler.Add(new Schueler { Name = "Anna Schmidt", Jahrgang = 2026 });
context.Schueler.Add(new Schueler { Name = "Ben Meyer", Jahrgang = 2025 });
context.SaveChanges();
// Alle Schueler ab Jahrgang 2025 ausgeben
var liste = context.Schueler
.Where(s => s.Jahrgang >= 2025)
.OrderBy(s => s.Name)
.ToList();
foreach (var s in liste)
{
Console.WriteLine($"{s.Id}: {s.Name} (Jahrgang {s.Jahrgang})");
}
}
}Beim ersten Start legt `EnsureCreated()` die Datenbankdatei samt Tabelle automatisch an. Beim zweiten Start kommen zwei neue Einträge dazu - die alten bleiben erhalten.
Welche typischen Fehler treten auf?
Die drei häufigsten Stolpersteine beim Datenbankzugriff aus C# kennst du jetzt schon - hier die Lösungen:
1. Fehlermeldung „no such table"
Meist fehlt `EnsureCreated()` oder die Datei liegt an einem anderen Ort, als du denkst. SQLite erstellt bei jedem Start eine leere Datei, wenn der Pfad nicht stimmt - prüf also den Connection String genau.
2. SQL-Injection-Warnung im Review
Niemals Benutzereingaben in SQL-Strings einbauen. Nutze Parameter wie oben gezeigt - bei ADO.NET mit `Parameters.AddWithValue`, bei EF Core passiert es automatisch.
3. „ObjectDisposedException" beim DbContext
Ein `DbContext`, den du mit `using` freigegeben hast, kann nicht wiederbelebt werden. Erstelle einfach eine neue Instanz - das ist normal und günstig. Zusätzlich solltest du Datenbankfehler gezielt abfangen, wie wir es im Artikel zum Exception Handling beschreiben.
FAQ: Häufige Fragen kurz beantwortet
Soll ich ADO.NET oder EF Core zuerst lernen?
ADO.NET zuerst. Du verstehst dann, was EF im Hintergrund macht - und SQL-Kenntnisse brauchst du sowieso, spätestens in der Prüfung.
Was ist ein Connection String?
Ein Text mit allen Verbindungsdaten, z. B. `Data Source=schulapp.db`. Er sagt dem Treiber, wohin die Verbindung gehen soll.
Funktioniert das auch mit SQL Server oder MySQL?
Ja. Du tauschst nur das NuGet-Paket und den Connection String - dein C#-Code bleibt fast identisch. EF Core nennt das Provider-Modell.
Was sind EF-Migrations?
Versionierte Skripte, die Datenbankänderungen (neue Tabellen, neue Spalten) nachvollziehbar umsetzen. Für den Einstieg reicht `EnsureCreated()`, für echte Projekte führt kein Weg an Migrations vorbei.
Brauche ich einen installierten Datenbankserver?
Nein. SQLite ist eine reine Datei und reicht für Lernprojekte und viele Ausbildungsnachweise völlig aus.
Fazit
Datenbankzugriff in C# läuft über zwei Wege: ADO.NET für direktes, kontrolliertes SQL und Entity Framework Core für objektorientierten Komfort. Starte mit ADO.NET, um SQL und die Mechanik zu verstehen - dann steig auf EF Core um, um schneller zu Ergebnissen zu kommen. Genau diese Kombination wird in Prüfung, Studium und Berufsalltag von dir erwartet.
Wenn du beim Nachbauen hängen bleibst oder für dein Abschlussprojekt eine Datenbankanbindung planst, helfe ich dir persönlich: Schau vorbei bei study-it.education und sichere dir deine individuelle Nachhilfe für C#, Datenbanken und alles rund um deine IT-Karriere.
1:1-Hilfe zu diesem Thema?
Brauchst du jemand, der das mit dir durchgeht?
Statt nochmal lesen: 30 min mit einem Senior-Dev.
Kostenloses Erstgespräch buchen →
So greifst du aus C# auf Datenbanken zu: mit ADO.NET für direktes SQL oder EF Core als modernem ORM – beide Wege mit Beispielen erklärt.
marcel.schmidtpeter@study-it.education →Mehr Lesestoff
C# JSON mit System.Text.Json lesen & schreiben – einfach erklärt
JSON-Daten in C# lesen und schreiben? Mit System.Text.Json gelingt dir Serialisierung & Deserialisierung – einfach erklärt für alle IT-Einsteiger.
C# xUnit Unit Test: So schreibst du deine ersten Unit Tests
Unit Tests mit xUnit machen deinen C#-Code belastbar. In diesem Tutorial lernst du [Fact], [Theory] und Assert kennen – für Einsteiger erklärt.
C# NuGet dotnet CLI: Pakete & Projekte einfach erklärt
Lerne, wie du C#-Projekte und Pakete mit NuGet und dotnet CLI verwaltest – mit praktischen Beispielen für Azubis, Studenten und Berufseinsteiger.