Skip to content

Data · Relationships

Orders

A master-detail graph loaded in one query: header, customer, lines, and each line's product. Status is an enum stored as TEXT, OrderedAt is a DateTimeOffset, and both foreign keys are Restrict - so the engine, not the UI, decides what may be deleted.

Client database OPFS

Fastest persistent tier. Real files in the origin private file system. Concurrent connections, no COOP/COEP.

Orders

Every order with its customer and its lines, newest first. Click a row to open its header and its lines in the panel under the table.

Try Move an order to Shipped. The SQL page holds a live query over this table - open it in a second tab and watch it re-run.
Live
NumberCustomerStatusOrderedShip byTotal

Detail

Select an order, or create one.

csharp Loading the graph
_orders = await context.Orders
    .AsNoTracking()
    .Include(o => o.Customer)
    .Include(o => o.Lines)
        .ThenInclude(l => l.Product)
    .OrderByDescending(o => o.Id)
    .ToListAsync();

Saving a header, then its lines

The header is saved first because the lines need its generated key, and the unit price is copied onto the line so later price changes do not rewrite history. Both saves go through the same connection in the same worker.

csharp Adding a line
// Header first: the line items need the generated key.
context.Orders.Add(order);
await context.SaveChangesAsync();

context.OrderLines.Add(new OrderLine
{
    OrderId = order.Id,
    ProductId = product.Id,
    Quantity = quantity,
    UnitPrice = product.Price,   // price is captured at line time
});

await context.SaveChangesAsync();
context.ChangeTracker.Clear();

Why the grid sorts by Id

A DateTimeOffset round-trips correctly, but SQLite has no type that can order one, so the stock SQLite provider refuses ORDER BY on it - on a server exactly as here. Bsqlite does not paper over that: same provider, same rules.

csharp Sorting a DateTimeOffset column
// DateTimeOffset round-trips as TEXT with its offset, but SQLite cannot compare it,
// so the stock SQLite provider refuses ORDER BY on it. Sort by the key instead:
.OrderByDescending(o => o.Id)

// ...and do offset-sensitive work in the CLR after materialising:
var latest = _orders.MaxBy(o => o.OrderedAt);

The relationships behind this page

Status is stored as TEXT so an exported .db stays readable and reordering the enum cannot silently change history. Deleting a customer who has orders, or a product on a line, is refused by Restrict.

csharp SalesOrderConfiguration.cs
An unhandled error has occurred. Reload 🗙