It is a framework/library that you created to simplify database connectivity in .NET applications.
- Provide common utilities for working with databases.
- Expose a clean API to your users, so they don’t have to configure EF Core themselves.
- Package EF Core and its dependencies inside your own NuGet package → when someone installs
Potato.NET.SQLite, all required dependencies come automatically.
It is a lightweight framework DLL that wires up Entity Framework Core + SQLite for desktop apps (WPF/WinForms/Console).
You define your own DbSet<T>s (tables) in a small context class and start saving data immediately.
- ✔️ Works with .NET 8
- ✔️ Uses EF Core 9 + SQLite
- ✔️ Simple configuration via
AppDbConfig - ✔️ Supports runtime
Database.Migrate()(no need to runUpdate-Databasemanually) - ✔️ Optional
TableMappingsfor dynamic access to sets
In Package Manager Console:
Install-Package Potato.NET.SQLiteOr with .NET CLI:
dotnet add package Potato.NET.SQLiteNote:
Potato.NET.SQLitebrings EF Core runtime dependencies. If you plan to scaffold migrations with EF tools (Add-Migration,Update-Database) in your app project, also install:Install-Package Microsoft.EntityFrameworkCore.Design Install-Package Microsoft.EntityFrameworkCore.Tools(The runtime does not require these; they’re only for design-time commands.)
// Usually at app startup (Program.cs for console, App.xaml.cs for WPF)
AppDbConfig.DbDirectory = @"C:\PotatoMenuApp"; // any absolute folder path
AppDbConfig.DbName = "potato.db";
// Ensure the directory exists
Directory.CreateDirectory(AppDbConfig.DbDirectory);Create a context that inherits from AppDbContext, then declare your DbSets (tables).
Put this in your app project:
public class MyAppDbContext : AppDbContext
{
// Define your tables here
public DbSet<YourModel> YourTable { get; set; }
public DbSet<OtherModel> OtherTable { get; set; }
}
// Example models
public class YourModel
{
public int Id { get; set; } // PK
public string Name { get; set; }
public string Age { get; set; }
public string Address { get; set; }
}
public class OtherModel
{
public int Id { get; set; } // PK
public string Description { get; set; }
}
AppDbContext(inside the library) already knows how to build the SQLite connection string fromAppDbConfig.
using var db = new MyAppDbContext();
db.Database.Migrate(); // Ensures the database is created and upgraded to the latest schemaPrefer
Migrate()overEnsureCreated()for real apps, because it supports schema changes over time.
If you want to access sets dynamically by string name elsewhere:
AppDbConfig.RegisterTable<YourModel>("YourTable");
AppDbConfig.RegisterTable<OtherModel>("OtherTable");db.YourTable.Add(new YourModel { Name = "Test Data", Age = "IT", Address = "JAPAN" });
db.SaveChanges();
foreach (var item in db.YourTable)
{
Console.WriteLine($"{item.Id}: {item.Name} / {item.Age} / {item.Address}");
}-
Console app (Program.cs):
AppDbConfig.DbDirectory = @"C:\PotatoMenuApp"; AppDbConfig.DbName = "potato.db"; Directory.CreateDirectory(AppDbConfig.DbDirectory); using var db = new MyAppDbContext(); db.Database.Migrate(); // now use db...
-
WPF (App.xaml.cs → OnStartup):
protected override async void OnStartup(StartupEventArgs e) { base.OnStartup(e); AppDbConfig.DbDirectory = @"C:\PotatoMenuApp"; AppDbConfig.DbName = "potato.db"; Directory.CreateDirectory(AppDbConfig.DbDirectory); // Avoid blocking the UI thread await Task.Run(() => { using var db = new MyAppDbContext(); db.Database.Migrate(); }); new MainWindow().Show(); }
All examples assume:
using var db = new MyAppDbContext();var row = new YourModel
{
Name = "Alice",
Age = "28",
Address = "Osaka"
};
db.YourTable.Add(row);
db.SaveChanges();// All rows
var all = db.YourTable.ToList();
// Filter
var inJapan = db.YourTable.Where(x => x.Address == "JAPAN").ToList();
// Single by Id (returns null if not found)
var id5 = db.YourTable.FirstOrDefault(x => x.Id == 5);
// Projections (select specific fields)
var names = db.YourTable.Select(x => new { x.Id, x.Name }).ToList();var target = db.YourTable.FirstOrDefault(x => x.Id == 5);
if (target != null)
{
target.Address = "Tokyo";
db.SaveChanges();
}// Set Address = "Tokyo" for everyone named "Alice"
db.YourTable
.Where(x => x.Name == "Alice")
.ExecuteUpdate(s => s.SetProperty(x => x.Address, x => "Tokyo"));var toDelete = db.YourTable.FirstOrDefault(x => x.Id == 5);
if (toDelete != null)
{
db.YourTable.Remove(toDelete);
db.SaveChanges();
}// Delete all where Address is null/empty
db.YourTable
.Where(x => string.IsNullOrEmpty(x.Address))
.ExecuteDelete();using var tx = db.Database.BeginTransaction();
try
{
db.YourTable.Add(new YourModel { Name = "Bob" });
db.SaveChanges();
db.OtherTable.Add(new OtherModel { Description = "Hello" });
db.SaveChanges();
tx.Commit();
}
catch
{
tx.Rollback();
throw;
}When your models change (e.g., add a new property), you create a migration once, and then let the app apply it at runtime:
- In Package Manager Console (pick the app project as Default project):
Add-Migration AddAgeToYourModel -Context MyAppDbContext- You can either run:
Update-Database -Context MyAppDbContextor just start the app — the call to db.Database.Migrate() applies it automatically.
If your
DbContextlives in a separate class library, specify both projects:Add-Migration AddAgeToYourModel -Context MyAppDbContext ` -Project YourDataProject -StartupProject YourAppProject Update-Database -Context MyAppDbContext ` -Project YourDataProject -StartupProject YourAppProject
If you prefer not to run Migrate() at runtime, you can always do:
Add-Migration DescriptiveName -Context MyAppDbContext
Update-Database -Context MyAppDbContextIf you registered mappings:
AppDbConfig.RegisterTable<YourModel>("YourTable");
AppDbConfig.RegisterTable<OtherModel>("OtherTable");You can resolve sets dynamically:
// Using the built-in EF API
var type = AppDbConfig.TableMappings["YourTable"]; // typeof(YourModel)
var set = db.Set(type); // returns DbSet for that entity typeOr (if the base context exposes a helper like GetDbSet<T>()):
var yourSet = db.GetDbSet<YourModel>();-
“No migrations were found…” when running
Update-DatabaseYou created the migration in a different project than your startup project. Use:Add-Migration Name -Context MyAppDbContext -Project YourDataProject -StartupProject YourAppProject Update-Database -Context MyAppDbContext -Project YourDataProject -StartupProject YourAppProject
-
Add-Migrationnot recognized Install tools in the app project:Install-Package Microsoft.EntityFrameworkCore.Tools Install-Package Microsoft.EntityFrameworkCore.Design
-
FileNotFoundException: Microsoft.EntityFrameworkCore.SqliteEnsure the app project references EF Core SQLite (transitive usually works, but if needed add explicitly):Install-Package Microsoft.EntityFrameworkCore.Sqlite -
App hangs on
Database.Migrate()- Close DB browser tools; delete any
.db-wal/.db-shmfiles near the DB. - Verify
AppDbConfig.DbDirectoryexists and is writable. - On WPF, run
Migrate()off the UI thread (see WPF example above). - If migrations live in a different assembly, confirm the correct context and assembly via commands.
- Close DB browser tools; delete any
-
DB updated somewhere else You might be writing to
bin\Debug\...vs. another absolute path. Always set an explicitAppDbConfig.DbDirectoryandDbName.
Licensed under Apache-2.0.
// 1) Configure DB location
AppDbConfig.DbDirectory = @"C:\PotatoMenuApp";
AppDbConfig.DbName = "potato.db";
Directory.CreateDirectory(AppDbConfig.DbDirectory);
// 2) Context + models (typically defined in your app project)
public class MyAppDbContext : AppDbContext
{
public DbSet<YourModel> YourTable { get; set; }
public DbSet<OtherModel> OtherTable { get; set; }
}
public class YourModel
{
public int Id { get; set; }
public string Name { get; set; }
public string Age { get; set; }
public string Address { get; set; }
}
public class OtherModel
{
public int Id { get; set; }
public string Description { get; set; }
}
// 3) Create/upgrade schema at runtime
using var db = new MyAppDbContext();
db.Database.Migrate();
// 4) Optional dynamic table name registration
AppDbConfig.RegisterTable<YourModel>("YourTable");
AppDbConfig.RegisterTable<OtherModel>("OtherTable");
// 5) CRUD
db.YourTable.Add(new YourModel { Name = "Test Data", Age = "IT", Address = "JAPAN" });
db.SaveChanges();
var first = db.YourTable.FirstOrDefault();
if (first != null)
{
first.Address = "Tokyo";
db.SaveChanges();
}
db.YourTable
.Where(x => x.Name == "Test Data")
.ExecuteUpdate(s => s.SetProperty(x => x.Age, _ => "29"));
db.YourTable
.Where(x => x.Name == "Obsolete")
.ExecuteDelete();
foreach (var item in db.YourTable)
{
Console.WriteLine($"{item.Id}: {item.Name} / {item.Age} / {item.Address}");
}