Grid Transaction API

Efficient delta updates using manual transaction APIs. Perfect for high-performance scenarios with millions of rows.

Manual Add Transaction

Use AddRowsAsync() to add rows without refreshing the entire grid.

Loading...
Total: 10 rows (Added via transaction API - no full refresh)
View Code
@code {
    private Grid<Order> addGrid;
    private List<Order> orders = new();

    private async Task AddSingleRow()
    {
        var newOrder = new Order { /* ... */ };
        
        // Add to data source
        orders.Add(newOrder);
        
        // Apply transaction - only new row is rendered!
        await addGrid.AddRowsAsync(newOrder);
    }

    private async Task AddMultipleRows()
    {
        var newOrders = GenerateOrders(5);
        orders.AddRange(newOrders);
        
        // Batch add - all 5 rows added in single transaction
        await addGrid.AddRowsAsync(newOrders.ToArray());
    }
}

Manual Update Transaction

Use UpdateRowsAsync() to update specific rows efficiently.

Loading...
11 pending orders
View Code
@code {
    private Grid<Order> updateGrid;
    private List<Order> orders = new();

    private async Task UpdateRandomRow()
    {
        if (updateOrders.Count == 0) return;
        
        var statuses = new[] { OrderStatus.Pending, OrderStatus.Shipped, OrderStatus.Delivered };
        var order = updateOrders[Random.Shared.Next(updateOrders.Count)];
        order.Amount = Math.Round((decimal)(Random.Shared.NextDouble() * 10000 + 100), 2);
        order.Status = statuses[Random.Shared.Next(statuses.Length)];
        
        await updateGrid.UpdateRowsAsync(order);
    }

    private async Task UpdateMultipleRows()
    {
        var statuses = new[] { OrderStatus.Pending, OrderStatus.Shipped, OrderStatus.Delivered };
        var ordersToUpdate = updateOrders.OrderBy(x => Random.Shared.Next()).Take(5).ToArray();
        
        foreach (var order in ordersToUpdate)
        {
            order.Amount = Math.Round((decimal)(Random.Shared.NextDouble() * 10000 + 100), 2);
            order.Status = statuses[Random.Shared.Next(statuses.Length)];
        }
        
        await updateGrid.UpdateRowsAsync(ordersToUpdate);
    }

    private async Task UpdateAllPending()
    {
        var pendingOrders = updateOrders.Where(o => o.Status == OrderStatus.Pending).ToArray();
        
        foreach (var order in pendingOrders)
            order.Status = OrderStatus.Shipped;
        
        await updateGrid.UpdateRowsAsync(pendingOrders);
    }
}

Manual Remove Transaction

Use RemoveRowsAsync() to remove rows without full grid refresh.

Loading...
30 rows remaining
View Code
@code {
    private Grid<Order> removeGrid;
    private List<Order> orders = new();
    private IReadOnlyCollection<Order> selectedOrders = Array.Empty<Order>();

    private async Task RemoveSelected()
    {
        // Remove from data source
        orders.RemoveAll(o => selectedOrders.Contains(o));
        
        // Apply transaction - only removed rows affected!
        await removeGrid.RemoveRowsAsync(selectedOrders.ToArray());
        
        selectedOrders = Array.Empty<Order>();
    }

    private async Task RemoveDelivered()
    {
        var delivered = orders.Where(o => o.Status == "Delivered").ToArray();
        
        // Remove from list
        orders.RemoveAll(o => delivered.Contains(o));
        
        // Batch remove - all removed in one transaction
        await removeGrid.RemoveRowsAsync(delivered);
    }
}

Combined Transaction Operations

Perform multiple operations (add, update, remove) simultaneously for complex scenarios.

Loading...

Total: 20 orders

Pending: 8 | Shipped: 4 | Delivered: 3

View Code
@code {
    private Grid<Order> combinedGrid;
    private List<Order> orders = new();

    private async Task ProcessOrders()
    {
        // 1. Ship pending orders (UPDATE)
        var toShip = orders.Where(o => o.Status == "Pending").ToArray();
        foreach (var order in toShip)
            order.Status = "Shipped";

        // 2. Archive delivered orders (REMOVE)
        var toArchive = orders.Where(o => o.Status == "Delivered").ToArray();
        orders.RemoveAll(o => toArchive.Contains(o));

        // 3. Add new incoming orders (ADD)
        var newOrders = GenerateOrders(3);
        orders.AddRange(newOrders);

        // Execute all operations in optimal sequence
        // Grid batches them into a single efficient transaction!
        await combinedGrid.UpdateRowsAsync(toShip);
        await combinedGrid.RemoveRowsAsync(toArchive);
        await combinedGrid.AddRowsAsync(newOrders.ToArray());
    }
}

Performance Comparison

Compare full refresh vs. transaction API performance

❌ Full Refresh (Slow)

// Remove 1 item from 10,000 rows
orders.Remove(order);
orders = new List<Order>(orders);  // Trigger re-render
// Result: ALL 9,999 rows re-rendered 🐌

✅ Transaction API (Fast)

// Remove 1 item from 10,000 rows
orders.Remove(order);
await grid.RemoveRowsAsync(order);
// Result: Only 1 row removed from DOM ⚡
An unhandled error has occurred. Reload 🗙