vb-database

Visual Basic Database Patterns

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "vb-database" with this command: npx skills add bobmatnyc/claude-mpm-skills/bobmatnyc-claude-mpm-skills-vb-database

Visual Basic Database Patterns

ADO.NET and Entity Framework patterns for VB.NET with focus on connection management, parameterized queries, and async operations.

ADO.NET Patterns

Connection Management

' ✅ Good: Using statement ensures disposal Public Async Function GetCustomersAsync() As Task(Of List(Of Customer)) Dim customers = New List(Of Customer)()

Using connection = New SqlConnection(connectionString)
    Await connection.OpenAsync()

    Using command = New SqlCommand("SELECT * FROM Customers WHERE IsActive = @isActive", connection)
        command.Parameters.AddWithValue("@isActive", True)

        Using reader = Await command.ExecuteReaderAsync()
            While Await reader.ReadAsync()
                customers.Add(New Customer With {
                    .Id = reader.GetInt32(0),
                    .Name = reader.GetString(1),
                    .Email = reader.GetString(2)
                })
            End While
        End Using
    End Using
End Using

Return customers

End Function

Parameterized Queries (Critical for SQL Injection Prevention)

' ✅ Good: Parameterized query Public Async Function FindCustomerAsync(email As String) As Task(Of Customer) Using connection = New SqlConnection(connectionString) Await connection.OpenAsync()

    Dim sql = "SELECT * FROM Customers WHERE Email = @email"
    Using command = New SqlCommand(sql, connection)
        command.Parameters.Add("@email", SqlDbType.NVarChar, 255).Value = email

        Using reader = Await command.ExecuteReaderAsync()
            If Await reader.ReadAsync() Then
                Return MapCustomer(reader)
            End If
        End Using
    End Using
End Using

Return Nothing

End Function

' ❌ BAD: String concatenation (SQL injection risk!) Dim sql = $"SELECT * FROM Customers WHERE Email = '{email}'" ' NEVER DO THIS!

Transaction Management

Public Async Function TransferFundsAsync(fromAccountId As Integer, toAccountId As Integer, amount As Decimal) As Task Using connection = New SqlConnection(connectionString) Await connection.OpenAsync()

    Using transaction = connection.BeginTransaction()
        Try
            ' Debit from account
            Using command = New SqlCommand("UPDATE Accounts SET Balance = Balance - @amount WHERE Id = @id", connection, transaction)
                command.Parameters.AddWithValue("@amount", amount)
                command.Parameters.AddWithValue("@id", fromAccountId)
                Await command.ExecuteNonQueryAsync()
            End Using

            ' Credit to account
            Using command = New SqlCommand("UPDATE Accounts SET Balance = Balance + @amount WHERE Id = @id", connection, transaction)
                command.Parameters.AddWithValue("@amount", amount)
                command.Parameters.AddWithValue("@id", toAccountId)
                Await command.ExecuteNonQueryAsync()
            End Using

            transaction.Commit()
        Catch ex As Exception
            transaction.Rollback()
            Throw
        End Try
    End Using
End Using

End Function

Bulk Operations

Public Async Function BulkInsertCustomersAsync(customers As List(Of Customer)) As Task Using connection = New SqlConnection(connectionString) Await connection.OpenAsync()

    ' Create DataTable
    Dim table = New DataTable()
    table.Columns.Add("Name", GetType(String))
    table.Columns.Add("Email", GetType(String))
    table.Columns.Add("CreatedAt", GetType(DateTime))

    For Each customer In customers
        table.Rows.Add(customer.Name, customer.Email, DateTime.Now)
    Next

    ' Bulk copy
    Using bulkCopy = New SqlBulkCopy(connection)
        bulkCopy.DestinationTableName = "Customers"
        bulkCopy.BatchSize = 1000
        Await bulkCopy.WriteToServerAsync(table)
    End Using
End Using

End Function

Entity Framework Core Patterns

DbContext Setup

Public Class AppDbContext Inherits DbContext

Public Property Customers As DbSet(Of Customer)
Public Property Orders As DbSet(Of Order)

Public Sub New(options As DbContextOptions(Of AppDbContext))
    MyBase.New(options)
End Sub

Protected Overrides Sub OnModelCreating(builder As ModelBuilder)
    ' Configure entity
    builder.Entity(Of Customer)(Sub(entity)
        entity.HasKey(Function(c) c.Id)
        entity.Property(Function(c) c.Name).IsRequired().HasMaxLength(200)
        entity.Property(Function(c) c.Email).IsRequired().HasMaxLength(255)
        entity.HasIndex(Function(c) c.Email).IsUnique()
    End Sub)

    ' Configure relationship
    builder.Entity(Of Order)(Sub(entity)
        entity.HasOne(Function(o) o.Customer) _
              .WithMany(Function(c) c.Orders) _
              .HasForeignKey(Function(o) o.CustomerId)
    End Sub)
End Sub

End Class

CRUD Operations

Public Class CustomerRepository Private ReadOnly context As AppDbContext

Public Sub New(context As AppDbContext)
    Me.context = context
End Sub

' Create
Public Async Function AddAsync(customer As Customer) As Task(Of Customer)
    context.Customers.Add(customer)
    Await context.SaveChangesAsync()
    Return customer
End Function

' Read
Public Async Function GetByIdAsync(id As Integer) As Task(Of Customer)
    Return Await context.Customers _
        .Include(Function(c) c.Orders) _
        .FirstOrDefaultAsync(Function(c) c.Id = id)
End Function

' Update
Public Async Function UpdateAsync(customer As Customer) As Task
    context.Customers.Update(customer)
    Await context.SaveChangesAsync()
End Function

' Delete
Public Async Function DeleteAsync(id As Integer) As Task
    Dim customer = Await context.Customers.FindAsync(id)
    If customer IsNot Nothing Then
        context.Customers.Remove(customer)
        Await context.SaveChangesAsync()
    End If
End Function

' Query with filtering
Public Async Function GetActiveCustomersAsync() As Task(Of List(Of Customer))
    Return Await context.Customers _
        .Where(Function(c) c.IsActive) _
        .OrderBy(Function(c) c.Name) _
        .ToListAsync()
End Function

End Class

Async Queries

' Single result Dim customer = Await context.Customers _ .FirstOrDefaultAsync(Function(c) c.Email = email)

' List results Dim customers = Await context.Customers _ .Where(Function(c) c.IsActive) _ .ToListAsync()

' Count Dim count = Await context.Customers.CountAsync()

' Any Dim exists = Await context.Customers _ .AnyAsync(Function(c) c.Email = email)

' Aggregate Dim totalOrders = Await context.Orders.SumAsync(Function(o) o.Amount)

Change Tracking

' Detach entity context.Entry(customer).State = EntityState.Detached

' Track changes Dim customer = Await context.Customers.FindAsync(id) customer.Name = "Updated Name"

' See what changed Dim entry = context.Entry(customer) For Each prop In entry.Properties If prop.IsModified Then Console.WriteLine($"{prop.Metadata.Name}: {prop.OriginalValue} -> {prop.CurrentValue}") End If Next

Await context.SaveChangesAsync()

Database Migrations

Code-First Migrations

Add migration

dotnet ef migrations add InitialCreate

Update database

dotnet ef database update

Rollback

dotnet ef database update PreviousMigration

Generate SQL script

dotnet ef migrations script

Migration Class

Public Class CreateCustomersTable Inherits Migration

Protected Overrides Sub Up(migrationBuilder As MigrationBuilder)
    migrationBuilder.CreateTable(
        name:="Customers",
        columns:=Function(table) New With {
            .Id = table.Column(Of Integer)(nullable:=False).Annotation("SqlServer:Identity", "1, 1"),
            .Name = table.Column(Of String)(maxLength:=200, nullable:=False),
            .Email = table.Column(Of String)(maxLength:=255, nullable:=False),
            .CreatedAt = table.Column(Of DateTime)(nullable:=False)
        },
        constraints:=Sub(table)
            table.PrimaryKey("PK_Customers", Function(x) x.Id)
            table.UniqueConstraint("UK_Customers_Email", Function(x) x.Email)
        End Sub
    )

    migrationBuilder.CreateIndex(
        name:="IX_Customers_Email",
        table:="Customers",
        column:="Email",
        unique:=True
    )
End Sub

Protected Overrides Sub Down(migrationBuilder As MigrationBuilder)
    migrationBuilder.DropTable(name:="Customers")
End Sub

End Class

Connection String Management

' appsettings.json { "ConnectionStrings": { "DefaultConnection": "Server=(localdb)\mssqllocaldb;Database=MyApp;Trusted_Connection=True;" } }

' Startup configuration Public Class Startup Public Sub ConfigureServices(services As IServiceCollection) services.AddDbContext(Of AppDbContext)(Sub(options) options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")) End Sub) End Sub End Class

Best Practices

✅ DO

' Use async methods Dim customers = Await context.Customers.ToListAsync()

' Use parameterized queries command.Parameters.AddWithValue("@email", email)

' Dispose connections Using connection = New SqlConnection(connectionString) End Using

' Use transactions for multiple operations Using transaction = connection.BeginTransaction()

' Use IQueryable for deferred execution Dim query As IQueryable(Of Customer) = context.Customers.Where(Function(c) c.IsActive)

❌ DON'T

' Don't concatenate SQL (SQL injection!) Dim sql = $"SELECT * FROM Users WHERE Email = '{email}'"

' Don't forget to dispose Dim connection = New SqlConnection(connectionString) ' No Using - leak!

' Don't block on async Dim result = GetDataAsync().Result ' Deadlock risk

' Don't load entire table when filtering Dim customers = context.Customers.ToList().Where(Function(c) c.IsActive) ' Loads all first! ' Better: context.Customers.Where(Function(c) c.IsActive).ToList()

Related Skills

  • vb-core: Core VB.NET patterns

  • vb-winforms: Windows Forms with database binding

  • test-driven-development: Testing database operations

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

drizzle-orm

No summary provided by upstream source.

Repository SourceNeeds Review
General

pydantic

No summary provided by upstream source.

Repository SourceNeeds Review
General

playwright-e2e-testing

No summary provided by upstream source.

Repository SourceNeeds Review
General

tailwind-css

No summary provided by upstream source.

Repository SourceNeeds Review