.github/copilot-instructions.md: kleine, reviewbare Änderungen und echte Verifikation.github/instructions/artifacts.instructions.md: kleine, explizite, verifizierbare Änderungen in artifacts/.github/instructions/artifacts-consumers-education.instructions.md: didaktische Klarheit, ein Hauptkonzept, Foliensatzbezug und Vergleich mit dem manuellen Beispiel.github/instructions/slides.instructions.md: knappe, gut scannbare FolienErstelle ein kleines agent-generated example für SQLite in einem Lehrprojekt dieses Repos.
Lies zuerst die relevanten Repository-Instructions und ermittle den zugehörigen Foliensatz.
Die Folien sind in md/quarto/ae/SQLite.qmd leer vorbereitet. Das bisherige Beispiel ist in
artifacts/consumers/education/csharp-recipes/SQLiteRecipe, stark veraltet und noch nicht in
einem eigenen Repository. Als Ziel-Repo habe ich
https://github.com/RobinNunkesser/csharp-maui-sqlite.git angelegt.
Dokumentiere die verwendeten Instructions und den exakten Prompt, füge beides in den
Foliensatz ein und vergleiche das Ergebnis mit dem bestehenden manuellen Beispiel.
Bevorzuge didaktische Klarheit, kleinen Scope und überprüfbare Ergebnisse.sqlite-net-pcl in einer MAUI-App einbinden*.Core, *.Infrastructure, *.App, *.Tests)ObservableObject, [ObservableProperty], [RelayCommand] mit CommunityToolkit.MvvmTodoItemEntity (Infrastructure) ↔︎ TodoItem (Core)MauiProgram.csFakeTodoRepositorycsharp-maui-sqlite/
├── SQLite.Core/ # Domain + Interface + ViewModel
├── SQLite.Infrastructure/ # sqlite-net-pcl Adapter
├── SQLite/ # MAUI App (Composition Root)
└── SQLite.Tests/ # xUnit (nur Core)
SQLite.Core kennt keine Persistenz-Technologie.SQLite.Infrastructure kennt sqlite-net-pcl, aber nicht MAUI.ObservableObject + [ObservableProperty] generieren INotifyPropertyChanged.[PrimaryKey]-Attribut: das gehört zur Infrastructure.[PrimaryKey, AutoIncrement] bleibt in der Infrastructure.public partial class TodoViewModel : ObservableObject
{
private readonly ITodoRepository _repository;
public ObservableCollection<TodoItem> Todos { get; } = [];
[ObservableProperty] private string _newTitle = string.Empty;
[RelayCommand] public async Task LoadAsync() { ... }
[RelayCommand] public async Task AddAsync() { ... }
[RelayCommand] public async Task ToggleDoneAsync(TodoItem item) { ... }
[RelayCommand] public async Task DeleteAsync(TodoItem item) { ... }
}[RelayCommand] generiert LoadCommand, AddCommand etc. automatisch.ITodoRepository — ohne MAUI und ohne SQLite testbar.FileSystem.AppDataDirectory ist nur im MAUI-Projekt verfügbar.internal class FakeTodoRepository : ITodoRepository
{
private readonly List<TodoItem> _items = [];
private int _nextId = 1;
public Task<List<TodoItem>> GetAllAsync() =>
Task.FromResult(_items.ToList());
public Task SaveAsync(TodoItem item)
{
if (item.Id == 0) { item.Id = _nextId++; _items.Add(item); }
return Task.CompletedTask;
}
public Task DeleteAsync(TodoItem item)
{
_items.RemoveAll(i => i.Id == item.Id);
return Task.CompletedTask;
}
}| Kriterium | Manuell (SQLiteRecipe) | Agent (csharp-maui-sqlite) |
|---|---|---|
| Architektur | 4 Projekte (veraltet) | Core / Infrastructure / App / Tests |
| Muster | proprietär, veraltet | MVVM, Ports & Adapters, DI |
| Unit Tests | keine | 5 xUnit-Tests |
| Didaktische Klarheit | niedrig (veraltet) | hoch (modern, schrittweise erklärbar) |
| Zielgruppe | – | fortgeschrittene Studierende |
sqlite-net-pcl.github/copilot-instructions.md: kleine, reviewbare Änderungen und echte Verifikation.github/instructions/artifacts-consumers-education.instructions.md: didaktische Klarheit, ein Hauptkonzept.github/instructions/slides.instructions.md: knappe, gut scannbare Foliencsharp-maui-efcore/
├── EFCore.Core/ # Domain + Interface + ViewModel
├── EFCore.Infrastructure/ # EF Core Adapter
├── EFCore/ # MAUI App (Composition Root)
└── EFCore.Tests/ # xUnit (nur Core)
csharp-maui-sqlite.internal class TodoDbContext : DbContext
{
private readonly string _dbPath;
public DbSet<TodoItem> Todos { get; set; } = null!;
public TodoDbContext(string dbPath) { _dbPath = dbPath; }
protected override void OnConfiguring(DbContextOptionsBuilder options)
=> options.UseSqlite($"Data Source={_dbPath}");
}internal — nur innerhalb der Infrastructure sichtbar.[PrimaryKey]-Attribut nötig: EF Core erkennt Id per Convention.public class EfCoreTodoRepository : ITodoRepository
{
private readonly string _dbPath;
public EfCoreTodoRepository(string dbPath)
{
_dbPath = dbPath;
using var ctx = CreateContext();
ctx.Database.EnsureCreated();
}
private TodoDbContext CreateContext() => new(_dbPath);
public async Task<List<TodoItem>> GetAllAsync()
{
await using var ctx = CreateContext();
return await ctx.Todos.ToListAsync();
}
// SaveAsync, DeleteAsync analog
}EnsureCreated() im Konstruktor statt im OnAppearing.| Aspekt | sqlite-net-pcl | EF Core |
|---|---|---|
| Entitäts-Mapping | TodoItemEntity + manuell |
TodoItem direkt (Convention) |
| Attribute | [PrimaryKey, AutoIncrement] |
keine |
| Kontext | SQLiteAsyncConnection |
DbContext (intern) |
| LINQ-Unterstützung | eingeschränkt | vollständig |
ITodoRepository, TodoItem, TodoViewModel) ist identisch.FakeTodoRepository funktioniert für beide Beispiele.| Kriterium | sqlite-net-pcl | EF Core |
|---|---|---|
| Paketgröße | klein | größer |
| API | eigene Klassen | vertrautes EF-Core-Muster |
| Migrations | nicht vorhanden | möglich |
| Zielgruppe | SQLite-Einführung | Wer EF Core schon kennt |