entity-framework

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Entity Framework Core Skill

Entity Framework Core Skill

Sorcha uses EF Core 9+ with PostgreSQL (Npgsql) as the primary relational data store. The codebase implements a layered repository pattern with generic and specialized repositories, soft delete via query filters, and automatic migrations on startup.
Sorcha 使用 EF Core 9+ 搭配 PostgreSQL(Npgsql)作为主要的关系型数据存储。代码库实现了分层仓储模式,包含通用和专用仓储,通过查询过滤器实现软删除,以及启动时自动执行迁移。

Quick Start

快速开始

Register DbContext with PostgreSQL

注册DbContext并关联PostgreSQL

csharp
// src/Common/Sorcha.Storage.EFCore/Extensions/EFCoreServiceExtensions.cs
services.AddDbContext<WalletDbContext>((sp, options) =>
{
    var dataSource = sp.GetRequiredService<NpgsqlDataSource>();
    options.UseNpgsql(dataSource, npgsql =>
    {
        npgsql.EnableRetryOnFailure(maxRetryCount: 10, maxRetryDelay: TimeSpan.FromSeconds(30), errorCodesToAdd: null);
        npgsql.MigrationsHistoryTable("__EFMigrationsHistory", "wallet");
    });
});
csharp
// src/Common/Sorcha.Storage.EFCore/Extensions/EFCoreServiceExtensions.cs
services.AddDbContext<WalletDbContext>((sp, options) =>
{
    var dataSource = sp.GetRequiredService<NpgsqlDataSource>();
    options.UseNpgsql(dataSource, npgsql =>
    {
        npgsql.EnableRetryOnFailure(maxRetryCount: 10, maxRetryDelay: TimeSpan.FromSeconds(30), errorCodesToAdd: null);
        npgsql.MigrationsHistoryTable("__EFMigrationsHistory", "wallet");
    });
});

Create a Migration

创建迁移脚本

bash
undefined
bash
undefined

From project directory containing DbContext

From project directory containing DbContext

dotnet ef migrations add InitialSchema --project src/Common/Sorcha.Wallet.Core --startup-project src/Services/Sorcha.Wallet.Service
undefined
dotnet ef migrations add InitialSchema --project src/Common/Sorcha.Wallet.Core --startup-project src/Services/Sorcha.Wallet.Service
undefined

Apply Migrations Programmatically

以编程方式应用迁移

csharp
// Startup pattern used in Sorcha services
var pending = await dbContext.Database.GetPendingMigrationsAsync();
if (pending.Any())
    await dbContext.Database.MigrateAsync();
csharp
// Startup pattern used in Sorcha services
var pending = await dbContext.Database.GetPendingMigrationsAsync();
if (pending.Any())
    await dbContext.Database.MigrateAsync();

Key Concepts

核心概念

ConceptUsageExample
DbContextSchema definition + change tracking
WalletDbContext
,
TenantDbContext
RepositoryData access abstraction
EFCoreRepository<T, TId, TContext>
Soft DeleteQuery filter on
DeletedAt
.HasQueryFilter(e => e.DeletedAt == null)
JSONBPostgreSQL JSON columns
.HasColumnType("jsonb")
ExecuteUpdateBulk updates without loading
ExecuteUpdateAsync(s => s.SetProperty(...))
概念用途示例
DbContext架构定义 + 变更追踪
WalletDbContext
,
TenantDbContext
Repository数据访问抽象
EFCoreRepository<T, TId, TContext>
Soft Delete基于
DeletedAt
的查询过滤器
.HasQueryFilter(e => e.DeletedAt == null)
JSONBPostgreSQL JSON列
.HasColumnType("jsonb")
ExecuteUpdate无需加载数据的批量更新
ExecuteUpdateAsync(s => s.SetProperty(...))

Common Patterns

常用模式

Repository with Optional Eager Loading

支持可选预加载的仓储

csharp
// src/Common/Sorcha.Wallet.Core/Repositories/EfCoreWalletRepository.cs
public async Task<WalletEntity?> GetByAddressAsync(string address, bool includeAddresses = false)
{
    IQueryable<WalletEntity> query = _context.Wallets;
    
    if (includeAddresses)
        query = query.Include(w => w.Addresses);
    
    return await query.AsNoTracking().FirstOrDefaultAsync(w => w.Address == address);
}
csharp
// src/Common/Sorcha.Wallet.Core/Repositories/EfCoreWalletRepository.cs
public async Task<WalletEntity?> GetByAddressAsync(string address, bool includeAddresses = false)
{
    IQueryable<WalletEntity> query = _context.Wallets;
    
    if (includeAddresses)
        query = query.Include(w => w.Addresses);
    
    return await query.AsNoTracking().FirstOrDefaultAsync(w => w.Address == address);
}

Soft Delete with Filter Bypass

绕过过滤器的软删除操作

csharp
// Bypass query filter for admin operations
var deleted = await _context.Wallets
    .IgnoreQueryFilters()
    .FirstOrDefaultAsync(w => w.Address == address);
csharp
// Bypass query filter for admin operations
var deleted = await _context.Wallets
    .IgnoreQueryFilters()
    .FirstOrDefaultAsync(w => w.Address == address);

See Also

相关参考

  • patterns - DbContext configuration, entity mapping, query optimization
  • workflows - Migration commands, testing patterns, deployment
  • patterns - DbContext配置、实体映射、查询优化
  • workflows - 迁移命令、测试模式、部署流程

Related Skills

相关技能

  • See the postgresql skill for connection configuration and PostgreSQL-specific features
  • See the aspire skill for service registration and health checks
  • See the xunit skill for testing DbContext with InMemory provider
  • 关于连接配置和PostgreSQL专属功能,请查看 postgresql 技能文档
  • 关于服务注册和健康检查,请查看 aspire 技能文档
  • 关于使用InMemory提供程序测试DbContext,请查看 xunit 技能文档

Documentation Resources

文档资源

Fetch latest EF Core documentation with Context7.
Library ID:
/dotnet/entityframework.docs
Recommended Queries:
  • "DbContext pooling configuration dependency injection"
  • "migrations code-first apply production deployment"
  • "query filters soft delete global filters"
  • "bulk operations ExecuteUpdate ExecuteDelete"
使用Context7获取最新的EF Core文档。
Library ID:
/dotnet/entityframework.docs
推荐查询语句:
  • "DbContext pooling configuration dependency injection"
  • "migrations code-first apply production deployment"
  • "query filters soft delete global filters"
  • "bulk operations ExecuteUpdate ExecuteDelete"