重要前提
安装AI Skills的关键前提是:必须科学上网,且开启TUN模式,这一点至关重要,直接决定安装能否顺利完成,在此郑重提醒三遍:科学上网,科学上网,科学上网。查看完整安装教程 →
vb-database by bobmatnyc/claude-mpm-skills
npx skills add https://github.com/bobmatnyc/claude-mpm-skills --skill vb-database专注于连接管理、参数化查询和异步操作的 VB.NET ADO.NET 和 Entity Framework 模式。
' ✅ 良好:使用 Using 语句确保释放资源
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
' ✅ 良好:参数化查询
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
' ❌ 错误:字符串拼接(SQL 注入风险!)
Dim sql = $"SELECT * FROM Customers WHERE Email = '{email}'" ' 永远不要这样做!
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
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
' 从账户扣款
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
' 向账户存款
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
Public Async Function BulkInsertCustomersAsync(customers As List(Of Customer)) As Task
Using connection = New SqlConnection(connectionString)
Await connection.OpenAsync()
' 创建 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
' 批量复制
Using bulkCopy = New SqlBulkCopy(connection)
bulkCopy.DestinationTableName = "Customers"
bulkCopy.BatchSize = 1000
Await bulkCopy.WriteToServerAsync(table)
End Using
End Using
End Function
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)
' 配置实体
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)
' 配置关系
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
Public Class CustomerRepository
Private ReadOnly context As AppDbContext
Public Sub New(context As AppDbContext)
Me.context = context
End Sub
' 创建
Public Async Function AddAsync(customer As Customer) As Task(Of Customer)
context.Customers.Add(customer)
Await context.SaveChangesAsync()
Return customer
End Function
' 读取
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
' 更新
Public Async Function UpdateAsync(customer As Customer) As Task
context.Customers.Update(customer)
Await context.SaveChangesAsync()
End Function
' 删除
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
' 带过滤的查询
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
' 单个结果
Dim customer = Await context.Customers _
.FirstOrDefaultAsync(Function(c) c.Email = email)
' 列表结果
Dim customers = Await context.Customers _
.Where(Function(c) c.IsActive) _
.ToListAsync()
' 计数
Dim count = Await context.Customers.CountAsync()
' 是否存在
Dim exists = Await context.Customers _
.AnyAsync(Function(c) c.Email = email)
' 聚合
Dim totalOrders = Await context.Orders.SumAsync(Function(o) o.Amount)
' 分离实体
context.Entry(customer).State = EntityState.Detached
' 跟踪变更
Dim customer = Await context.Customers.FindAsync(id)
customer.Name = "Updated Name"
' 查看变更内容
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()
# 添加迁移
dotnet ef migrations add InitialCreate
# 更新数据库
dotnet ef database update
# 回滚
dotnet ef database update PreviousMigration
# 生成 SQL 脚本
dotnet ef migrations script
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
' appsettings.json
{
"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=MyApp;Trusted_Connection=True;"
}
}
' 启动配置
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
' 使用异步方法
Dim customers = Await context.Customers.ToListAsync()
' 使用参数化查询
command.Parameters.AddWithValue("@email", email)
' 释放连接
Using connection = New SqlConnection(connectionString)
End Using
' 为多个操作使用事务
Using transaction = connection.BeginTransaction()
' 使用 IQueryable 进行延迟执行
Dim query As IQueryable(Of Customer) = context.Customers.Where(Function(c) c.IsActive)
' 不要拼接 SQL(SQL 注入!)
Dim sql = $"SELECT * FROM Users WHERE Email = '{email}'"
' 不要忘记释放资源
Dim connection = New SqlConnection(connectionString) ' 没有 Using - 内存泄漏!
' 不要在异步方法上阻塞
Dim result = GetDataAsync().Result ' 死锁风险
' 在过滤时不要加载整个表
Dim customers = context.Customers.ToList().Where(Function(c) c.IsActive) ' 先加载所有数据!
' 更好:context.Customers.Where(Function(c) c.IsActive).ToList()
每周安装次数
37
仓库
GitHub 星标数
20
首次出现
2026年2月14日
安全审计
已安装于
codex33
gemini-cli31
opencode31
cursor30
amp30
github-copilot30
ADO.NET and Entity Framework patterns for VB.NET with focus on connection management, parameterized queries, and async operations.
' ✅ 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
' ✅ 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!
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
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
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
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
' 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)
' 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()
# 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
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
' 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
' 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 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()
Weekly Installs
37
Repository
GitHub Stars
20
First Seen
Feb 14, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykWarn
Installed on
codex33
gemini-cli31
opencode31
cursor30
amp30
github-copilot30
Firestore 基础入门指南 - 配置、安全规则、SDK 使用与索引优化
1,300 周安装