VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 编程开发 > c#编程 >
  • EF Core CRUD——c#处理用户信息管理

第一部分:C#基础入门
5.EF Core CRUD——用户信息管理
实例介绍
EF Core的CRUD操作(创建Create、读取Read、更新Update、删除Delete)是ORM框架的核心能力,也是日常开发中最频繁的操作。通过EF Core,你可以用面向对象的方式完成数据库的增删改查,无需手写SQL语句。本节通过“用户信vb.net教程C#教程python教程SQL教程access 2010教程
息管理系统”场景,带你掌握EF Core的CRUD全流程,包括异步操作、乐观锁、跟踪机制等关键知识点,让你真正学会“用代码操作数据库”。
需求分析
设计一个用户信息管理工具,核心需求:
1.实体映射:将User类映射到Users表,包含Id(主键)、UserName(用户名)、Email(邮箱)、CreateTime(创建时间)、LastUpdateTime(最后更新时间);
2.CRUD操作:
1.创建:新增用户并自动填充创建时间;
2.读取:查询单用户(ById)、查询所有用户、按条件查询(如按邮箱模糊查询);
3.更新:修改用户信息并自动更新最后更新时间,处理并发冲突;
4.删除:按Id删除用户;
3.性能优化:使用异步方法提升并发性能,非跟踪查询减少内存占用;
4.并发控制:通过乐观锁防止多用户同时更新同一数据导致的冲突;
5.测试验证:覆盖所有CRUD场景,验证操作正确性。
代码实现
前置条件:
安装EF Core包:Microsoft.EntityFrameworkCore、Microsoft.EntityFrameworkCore.SqlServer;
创建数据库UserDB(或复用现有数据库);

  1. 实体类定义(含乐观锁)
    csharp
	using System;
	using System.ComponentModel.DataAnnotations;
	using System.ComponentModel.DataAnnotations.Schema;
	
	/// <summary>
	/// 用户实体:映射到Users表
	/// </summary>
	[Table("Users")]
	public class User {
	/// <summary>
	/// 主键:自增ID
	/// </summary>
	[Key]
	[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
	public int Id { get; set; }
	
	/// <summary>
	/// 用户名:非空,最大长度50
	/// </summary>
	[Required]
	[MaxLength(50)]
	public string UserName { get; set; }
	
	/// <summary>
	/// 邮箱:非空,唯一,最大长度100
	/// </summary>
	[Required]
	[MaxLength(100)]
	[EmailAddress]
	public string Email { get; set; }
	
	/// <summary>
	/// 创建时间:自动填充,不可修改
	/// </summary>
	[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
	public DateTime CreateTime { get; set; }
	
	/// <summary>
	/// 最后更新时间:自动更新
	/// </summary>
	public DateTime LastUpdateTime { get; set; }
	
	/// <summary>
	/// 并发令牌:用于乐观锁
	/// </summary>
	[ConcurrencyCheck]
	public byte[] RowVersion { get; set; }
	}
2. DbContext配置(含Fluent API优化)
csharp 
	using Microsoft.EntityFrameworkCore;
	
	/// <summary>
	/// 用户数据库上下文
	/// </summary>
	public class UserDbContext : DbContext {
	// 连接字符串:替换为你的数据库连接
	private const string ConnectionString = @"Data Source=(localdb)MSSQLLocalDB;Initial Catalog=UserDB;Integrated Security=True;";
	
	// DbSet:对应Users表
	public DbSet<User> Users { get; set; }
	
	/// <summary>
	/// 配置数据库连接
	/// </summary>
	protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) {
	optionsBuilder.UseSqlServer(ConnectionString)
	.LogTo(Console.WriteLine) // 输出SQL日志(调试用)
	.EnableSensitiveDataLogging(); // 显示敏感数据(调试用)
	}
	
	/// <summary>
	/// Fluent API:实体映射配置
	/// </summary>
	protected override void OnModelCreating(ModelBuilder modelBuilder) {
	// 配置User实体
	modelBuilder.Entity<User>(entity => {
	// 表名确认
	entity.ToTable("Users");
	
	// 邮箱唯一约束
	entity.HasIndex(u => u.Email).IsUnique();
	
	// 最后更新时间:自动设置为当前时间(插入/更新时)
	entity.Property(u => u.LastUpdateTime)
	.HasDefaultValueSql("GETDATE()")
	.ValueGeneratedOnAddOrUpdate();
	
	// 并发令牌:使用RowVersion作为乐观锁
	entity.Property(u => u.RowVersion)
	.IsRowVersion(); // SQL Server的timestamp类型(自动生成)
	});
	}
	}
  1. CRUD核心实现(异步方法)
    csharp
	using System;
	using System.Collections.Generic;
	using System.Linq;
	using System.Threading.Tasks;
	using Microsoft.EntityFrameworkCore;
	
	/// <summary>
	/// 用户信息CRUD服务
	/// </summary>
	public class UserService {
	private readonly UserDbContext _dbContext;
	
	/// <summary>
	/// 构造函数:注入DbContext
	/// </summary>
	public UserService(UserDbContext dbContext) {
	_dbContext = dbContext;
	}
	
	/// <summary>
	/// 创建用户(异步)
	/// </summary>
	public async Task<int> CreateUserAsync(User user) {
	// 标记实体为Added状态
	await _dbContext.Users.AddAsync(user);
	// 保存到数据库,返回受影响的行数
	return await _dbContext.SaveChangesAsync();
	}
	
	/// <summary>
	/// 根据ID查询用户(异步)
	/// </summary>
	public async Task<User> GetUserByIdAsync(int id) {
	// FindAsync:根据主键查询,优先从ChangeTracker获取
	return await _dbContext.Users.FindAsync(id);
	}
	
	/// <summary>
	/// 查询所有用户(异步,非跟踪)
	/// </summary>
	public async Task<List<User>> GetAllUsersAsync() {
	// AsNoTracking:关闭跟踪,提升查询性能(只读场景)
	return await _dbContext.Users.AsNoTracking().ToListAsync();
	}
	
	/// <summary>
	/// 根据邮箱模糊查询用户(异步)
	/// </summary>
	public async Task<List<User>> GetUsersByEmailAsync(string emailKeyword) {
	return await _dbContext.Users
	.Where(u => u.Email.Contains(emailKeyword))
	.AsNoTracking()
	.ToListAsync();
	}
	
	/// <summary>
	/// 更新用户信息(异步,处理并发冲突)
	/// </summary>
	public async Task<bool> UpdateUserAsync(User user) {
	try {
	// 标记实体为Modified状态
	_dbContext.Users.Update(user);
	// 保存更改:若并发令牌不匹配,抛出DbUpdateConcurrencyException
	await _dbContext.SaveChangesAsync();
	return true;
	} catch (DbUpdateConcurrencyException) {
	// 并发冲突处理:返回false或重新查询数据
	return false;
	}
	}
	
	/// <summary>
	/// 删除用户(异步)
	/// </summary>
	public async Task<int> DeleteUserAsync(int id) {
	// 先查询用户
	var user = await _dbContext.Users.FindAsync(id);
	if (user == null) return 0;
	
	// 标记实体为Deleted状态
	_dbContext.Users.Remove(user);
	// 保存更改
	return await _dbContext.SaveChangesAsync();
	}
	}
  1. 测试代码(验证CRUD)
    csharp
	using System;
	using System.Threading.Tasks;
	
	class Program {
	static async Task Main(string[] args) {
	// 创建DbContext实例
	using var dbContext = new UserDbContext();
	// 初始化CRUD服务
	var userService = new UserService(dbContext);
	
	// 1. 创建用户
	var newUser = new User {
	UserName = "Alice",
	Email = "alice@example.com"
	};
	var createResult = await userService.CreateUserAsync(newUser);
	Console.WriteLine($"创建用户结果:{createResult}行受影响,用户ID:{newUser.Id}");
	
	// 2. 查询用户
	var user = await userService.GetUserByIdAsync(newUser.Id);
	Console.WriteLine($"查询用户:ID={user.Id},Name={user.UserName},Email={user.Email}");
	
	// 3. 更新用户
	user.UserName = "Alice_Updated";
	var updateResult = await userService.UpdateUserAsync(user);
	Console.WriteLine($"更新用户结果:{updateResult ? "成功" : "失败(并发冲突)"}");
	
	// 4. 查询所有用户
	var allUsers = await userService.GetAllUsersAsync();
	Console.WriteLine($"所有用户数量:{allUsers.Count}");
	
	// 5. 删除用户
	var deleteResult = await userService.DeleteUserAsync(newUser.Id);
	Console.WriteLine($"删除用户结果:{deleteResult}行受影响");
	}
	}

逐行讲解

  1. 实体类关键代码
    [Key] + [DatabaseGenerated]:标记Id为主键,自增生成;
    [ConcurrencyCheck] + RowVersion:RowVersion作为并发令牌,SQL Server自动生成timestamp类型,用于乐观锁;
    [DatabaseGenerated(Computed)]:CreateTime由数据库计算生成(插入时自动填充当前时间);
  2. DbContext关键代码
    OnConfiguring:配置SQL Server连接,启用日志和敏感数据显示(调试用);
    OnModelCreating:
    HasIndex(u=>u.Email).IsUnique:邮箱列添加唯一约束,防止重复;
    HasDefaultValueSql("GETDATE()"):LastUpdateTime默认值为当前时间,插入/更新时自动更新;
    IsRowVersion():将RowVersion映射为SQL Server的timestamp类型,自动生成并更新;
  3. CRUD服务关键代码
    CreateUserAsync:AddAsync标记实体为Added状态,SaveChangesAsync提交到数据库;
    GetUserByIdAsync:FindAsync根据主键查询,优先从ChangeTracker(跟踪缓存)获取,性能更高;
    GetAllUsersAsync:AsNoTracking关闭跟踪,减少内存占用,适合只读场景;
    UpdateUserAsync:Update标记实体为Modified状态,若并发令牌不匹配(如其他用户已更新),抛出DbUpdateConcurrencyException;
    DeleteUserAsync:先查询用户,再标记为Deleted状态,最后提交;
  4. 测试代码关键逻辑
    async/await:异步操作避免阻塞主线程,适合高并发场景;
    using var dbContext:自动释放DbContext资源;
    CreateUserAsync:创建后newUser.Id会自动填充(自增主键);
    基础知识拓展
  5. EF Core跟踪机制(ChangeTracker)
    跟踪状态:EF Core自动跟踪实体的状态(Added/Modified/Deleted/Unchanged),SaveChangesAsync根据状态生成对应的SQL;
    ChangeTracker:可通过_dbContext.ChangeTracker查看实体状态,手动修改状态(如_dbContext.Entry(user).State = EntityState.Modified);
    非跟踪查询:AsNoTracking关闭跟踪,实体不会被ChangeTracker缓存,适合只读场景,性能提升明显;
  6. 乐观锁原理与应用
    乐观锁:假设并发冲突很少发生,仅在提交时检查数据是否被修改;
    实现方式:通过RowVersion(timestamp)或ConcurrencyToken标记列,更新时比较列值是否一致;
    并发冲突处理:捕获DbUpdateConcurrencyException,重新查询最新数据并提示用户重试;
  7. 异步操作的好处
    非阻塞:异步方法不会阻塞调用线程,主线程可处理其他任务,提升应用响应速度;
    高并发:适合Web API、后台服务等需要处理大量请求的场景;
    EF Core异步方法:所有CRUD操作都有对应的异步版本(如AddAsync、SaveChangesAsync),避免阻塞IO线程;
  8. 查询优化技巧
    投影查询:使用Select只查询需要的列,减少数据传输(如_dbContext.Users.Select(u=>new {u.Id, u.UserName}));
    关联查询:Include加载关联数据(如_dbContext.Users.Include(u=>u.Orders));
    分页查询:Skip+Take实现分页(如_dbContext.Users.Skip(10).Take(10));
  9. 批量操作优化
    EF Core默认限制:单条操作性能低,批量操作需第三方库(如EFCore.BulkExtensions);
    批量操作:BulkInsert、BulkUpdate、BulkDelete等方法,大幅提升大量数据操作性能;
    总结
    EF Core的CRUD操作是ORM开发的基础,通过实体映射、DbContext配置和异步方法,可快速实现高效、安全的数据库操作。关键知识点包括:
    跟踪机制:ChangeTracker自动管理实体状态;
    乐观锁:RowVersion处理并发冲突;
    异步操作:提升高并发场景性能;
    查询优化:AsNoTracking、投影查询、分页等;
    掌握这些知识点后,你可以进一步学习EF Core的高级特性(如迁移、事务、存储过程、批量操作),构建更复杂的应用系统。

本站原创,转载请注明出处:https://www.xin3721.com/ArticlecSharp/c49438.html


相关教程