using System; using System.Linq; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore; await using var connection = new SqliteConnection("Data Source=:memory:;Foreign Keys=True"); await connection.OpenAsync(); var options = new DbContextOptionsBuilder().UseSqlite(connection).Options; await using (var db = new LabDb(options)) { await db.Database.EnsureCreatedAsync(); db.Blogs.Add(new Blog { Name = "A", Posts = { new Post { Title = "First" } } }); await db.SaveChangesAsync(); var row = await db.Posts.Include(p => p.Blog).SingleAsync(); Check(row.BlogId > 0 && row.Blog.Name == "A", "saved FK graph"); Console.WriteLine("related:" + row.Blog.Name); } bool rejected = false; await using (var invalid = new LabDb(options)) { invalid.Posts.Add(new Post { Title = "Orphan", BlogId = 9999 }); try { await invalid.SaveChangesAsync(); } catch (DbUpdateException ex) when (ex.InnerException is SqliteException { SqliteErrorCode: 19, SqliteExtendedErrorCode: 787 }) { rejected = true; } } await using (var verify = new LabDb(options)) Check(rejected && await verify.Posts.CountAsync() == 1, "foreign key rejected without orphan"); Console.WriteLine("foreign-key:rejected"); static void Check(bool condition, string name) { if (!condition) throw new InvalidOperationException("CHECK: " + name); }