mcpField
E
entity-framework-core

entity-framework-core

github.com/claude-dev-suite开发4665 次安装4 天前更新
代码仓库

关于 entity-framework-core

面向 .NET 开发者的 Entity Framework Core 速查技能,介绍 DbContext、实体配置、迁移和 LINQ 查询。内容也包括查询性能建议与常见问题排查。

主要功能

  1. 01DbContext 配置
  2. 02Fluent API 实体配置
  3. 03数据库迁移命令
  4. 04LINQ 查询与投影
  5. 05只读和批量操作优化
  6. 06常见问题排查

适用场景

  1. 01配置数据库上下文和实体
  2. 02执行迁移以更新数据库
  3. 03优化只读查询和批量操作

MCP 相关

提及可通过 `mcp__documentation__fetch_docs` 获取 Entity Framework Core 的深入文档。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/claude-dev-suite/claude-dev-suite --skill entity-framework-core

安装后在 Claude Code 中输入/entity-framework-core确认已加载。

详细介绍

Entity Framework Core - 快速参考

深入了解:使用 mcp__documentation__fetch_docs,并指定技术:entity-framework-core,获取完整文档。

DbContext 设置

public class AppDbContext : DbContext
{
    public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }

    public DbSet<User> Users => Set<User>();
    public DbSet<Order> Orders => Set<Order>();

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.ApplyConfigurationsFromAssembly(typeof(AppDbContext).Assembly);
    }
}

// Registration
builder.Services.AddDbContext<AppDbContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("Default")));

实体配置(Fluent API)

public class UserConfiguration : IEntityTypeConfiguration<User>
{
    public void Configure(EntityTypeBuilder<User> builder)
    {
        builder.HasKey(u => u.Id);
        builder.Property(u => u.Name).IsRequired().HasMaxLength(100);
        builder.Property(u => u.Email).IsRequired().HasMaxLength(255);
        builder.HasIndex(u => u.Email).IsUnique();

        // Relationships
        builder.HasMany(u => u.Orders)
            .WithOne(o => o.User)
            .HasForeignKey(o => o.UserId)
            .OnDelete(DeleteBehavior.Cascade);

        // Value conversion
        builder.Property(u => u.Status)
            .HasConversion<string>();

        // Default values
        builder.Property(u => u.CreatedAt)
            .HasDefaultValueSql("GETUTCDATE()");
    }
}

迁移

# Add migration
dotnet ef migrations add InitialCreate

# Update database
dotnet ef database update

# Remove last migration (not applied)
dotnet ef migrations remove

# Generate SQL script
dotnet ef migrations script

# Revert to specific migration
dotnet ef database update MigrationName

LINQ 查询

// Basic queries
var user = await context.Users.FindAsync(id);
var users = await context.Users.Where(u => u.IsActive).ToListAsync();
var user = await context.Users.FirstOrDefaultAsync(u => u.Email == email);

// Projection
var dtos = await context.Users
    .Where(u => u.IsActive)
    .Select(u => new UserResponse(u.Id, u.Name, u.Email))
    .ToListAsync();

// Include related data
var usersWithOrders = await context.Users
    .Include(u => u.Orders)
    .ThenInclude(o => o.OrderItems)
    .ToListAsync();

// Pagination
var page = await context.Users
    .OrderBy(u => u.Name)
    .Skip((pageNumber - 1) * pageSize)
    .Take(pageSize)
    .ToListAsync();

// Aggregation
var count = await context.Users.CountAsync(u => u.IsActive);
var avgAge = await context.Users.AverageAsync(u => u.Age);

仓储模式

public interface IRepository<T> where T : class
{
    Task<T?> GetByIdAsync(int id);
    Task<IEnumerable<T>> GetAllAsync();
    Task AddAsync(T entity);
    void Update(T entity);
    void Remove(T entity);
    Task<bool> ExistsAsync(Expression<Func<T, bool>> predicate);
    Task SaveChangesAsync();
}

public class Repository<T> : IRepository<T> where T : class
{
    protected readonly AppDbContext _context;
    protected readonly DbSet<T> _dbSet;

    public Repository(AppDbContext context)
    {
        _context = context;
        _dbSet = context.Set<T>();
    }

    public async Task<T?> GetByIdAsync(int id) => await _dbSet.FindAsync(id);
    public async Task<IEnumerable<T>> GetAllAsync() => await _dbSet.ToListAsync();
    public async Task AddAsync(T entity) => await _dbSet.AddAsync(entity);
    public void Update(T entity) => _dbSet.Update(entity);
    public void Remove(T entity) => _dbSet.Remove(entity);
    public async Task<bool> ExistsAsync(Expression<Func<T, bool>> predicate)
        => await _dbSet.AnyAsync(predicate);
    public async Task SaveChangesAsync() => await _context.SaveChangesAsync();
}

性能提示

提示实现方式
只读时使用 AsNoTracking()context.Users.AsNoTracking().ToListAsync()
使用 Select 投影避免加载完整实体
使用 AsSplitQuery()防止使用 include 时发生笛卡尔积爆炸
使用已编译查询在热点路径使用 EF.CompileAsyncQuery(...)
批量操作ExecuteUpdateAsync / ExecuteDeleteAsync(EF Core 7+)
// Bulk update (EF Core 7+)
await context.Users
    .Where(u => u.LastLoginAt < cutoff)
    .ExecuteUpdateAsync(u => u.SetProperty(x => x.IsActive, false));

// Bulk delete
await context.Users
    .Where(u => u.IsDeleted)
    .ExecuteDeleteAsync();

反模式

反模式问题正确做法
为显示而加载完整实体浪费内存、速度慢使用 Select 投影
N+1 查询严重影响性能使用 Include 或投影
未使用 AsNoTracking产生不必要的开销用于只读查询
每个实体都调用 SaveChanges批量操作速度慢完成所有更改后调用一次
将 DbContext 用作单例存在线程安全问题使用 AddDbContext(Scoped)

快速故障排除

问题可能原因解决方案
跟踪冲突实体已被跟踪使用 AsNoTracking 或分离实体
迁移失败模型不匹配检查待处理的更改,然后重新构建
查询缓慢缺少索引在配置中添加 HasIndex
延迟加载失败未配置使用 Include(显式加载)
并发冲突数据过时添加 [ConcurrencyCheck] 或 RowVersion

评论

支持 Markdown