Entity Framework全栈核武器实战
🔧 模块1:ORM映射机制——“对象与数据库的量子纠缠”
1.1 实体类定义
// 学生实体(带导航属性)
public class Student
{
public int StudentId { get; set; }
public string Name { get; set; }
public DateTime EnrollmentDate { get; set; }
// 一对多关系:学生与选课
public ICollection<Course> Enrollments { get; set; } = new List<Course>();
// 多对多关系:学生与社团
public ICollection<Club> Clubs { get; set; } = new List<Club>();
}
// 课程实体
public class Course
{
public int CourseId { get; set; }
public string Title { get; set; }
public int Credits { get; set; }
// 导航属性:课程所属教师
public int TeacherId { get; set; }
public Teacher Teacher { get; set; }
}
// 教师实体(带复杂约束)
public class Teacher : IEntity // 继承基础接口
{
public int TeacherId { get; set; }
public string FullName { get; set; }
public string Department { get; set; }
// 多对一:教师与课程
public ICollection<Course> Courses { get; set; } = new List<Course>();
}
1.2 数据注解配置
// 使用DataAnnotations进行字段约束
public class Product
{
[Key] // 主键
public int ProductId { get; set; }
[Required(ErrorMessage = "名称必填")] // 非空约束
[StringLength(100, MinimumLength = 3)] // 长度限制
public string Name { get; set; }
[Column(TypeName = "decimal(18,2)")] // 数据库类型映射
public decimal Price { get; set; }
[Timestamp] // 乐观锁版本控制
public byte[] RowVersion { get; set; }
}
1.3 Fluent API配置
// 在DbContext的OnModelCreating中配置复杂关系
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// 1. 多对多关系配置(学生与社团)
modelBuilder.Entity<Student>()
.HasMany(s => s.Clubs)
.WithMany(c => c.Members)
.UsingEntity<Dictionary<string, object>>(
"StudentClub",
sc => sc.HasOne<Club>().WithMany().HasForeignKey("ClubId"),
sc => sc.HasOne<Student>().WithMany().HasForeignKey("StudentId"),
sc => sc.Property<Guid>("Id").ValueGeneratedOnAdd()
);
// 2. 复杂外键约束(教师与课程)
modelBuilder.Entity<Course>()
.HasOne(c => c.Teacher)
.WithMany(t => t.Courses)
.HasForeignKey(c => c.TeacherId)
.OnDelete(DeleteBehavior.Restrict); // 级联限制
// 3. 表名与字段名映射
modelBuilder.Entity<Order>()
.ToTable("tblOrders")
.Property(o => o.OrderDate)
.HasColumnName("OrderDateTime");
}
🔥 模块2:查询语言——“LINQ的时空穿越”
2.1 基础查询
// 使用LINQ查询学生信息
var students = dbContext.Students
.Where(s => s.EnrollmentDate >= DateTime.Now.AddYears(-3)) // 过滤近三年学生
.Include(s => s.Enrollments) // 预加载选课信息(解决N+1问题)
.ThenInclude(e => e.Course) // 二级预加载
.OrderByDescending(s => s.GPA)
.Take(10)
.ToList();
2.2 复杂查询与性能优化
// 使用原始SQL与EF结合(性能核爆)
var sql = @"
SELECT
s.Name,
AVG(c.Credits) AS AvgCredits
FROM Students s
JOIN Enrollments e ON s.StudentId = e.StudentId
JOIN Courses c ON e.CourseId = c.CourseId
GROUP BY s.Name
HAVING AVG(c.Credits) > @0";
var results = dbContext.Database
.SqlQuery<Report>(sql, 3.5)
.ToList();
// 使用跟踪禁用(NoTracking)提升读取性能
var fastQuery = dbContext.Products
.AsNoTracking() // 禁用变更跟踪
.Where(p => p.Price > 100)
.AsParallel() // 并行查询(EF Core 8+)
.ToList();
2.3 延迟加载与即时加载
// 延迟加载(默认启用)
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
// 延迟加载导航属性
public virtual ICollection<Post> Posts { get; set; }
}
// 即时加载(通过Include)
var blogs = dbContext.Blogs
.Include(b => b.Posts.Take(5)) // 预加载前5篇帖子
.ToList();
🌟 模块3:数据上下文——“DbContext的核爆管理”
3.1 DbContext核心配置
// 自定义DbContext实现
public class SchoolDbContext : DbContext
{
public DbSet<Student> Students { get; set; }
public DbSet<Course> Courses { get; set; }
public DbSet<Teacher> Teachers { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
// 多数据库支持(SQL Server/MySQL)
optionsBuilder.UseSqlServer(
"Server=localhost;Database=SchoolDB;Trusted_Connection=True;",
sqlOptions => sqlOptions.CommandTimeout(60)
);
}
// 事务管理(核爆级)
public async Task<int> SaveWithTransaction()
{
using (var transaction = await Database.BeginTransactionAsync())
{
try
{
// 执行多个操作
await SaveChangesAsync();
await transaction.CommitAsync();
return 1;
}
catch (Exception)
{
await transaction.RollbackAsync();
throw;
}
}
}
}
3.2 高级上下文模式
// 分层上下文(多数据库连接)
public class OrderDbContext : DbContext
{
public DbSet<Order> Orders { get; set; }
public DbSet<Customer> Customers { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseMySQL(
"Server=mysql.orders.com;Database=OrdersDB;User=app;Password=secure;"
);
}
}
// 使用依赖注入(ASP.NET Core)
services.AddDbContext<OrderDbContext>(options =>
options.UseMySQL(Configuration.GetConnectionString("Orders")));
3.3 避免N+1查询
// 使用Include优化(预加载)
var posts = dbContext.Blogs
.Where(b => b.Id == 1)
.Include(b => b.Posts.Select(p => p.Comments)) // 三级预加载
.FirstOrDefault();
// 使用投影(避免过度加载)
var report = dbContext.Employees
.Select(e => new EmployeeReport
{
Name = e.Name,
Department = e.Department.Name,
TotalSales = e.Sales.Sum(s => s.Amount)
})
.ToList();
🔥 模块4:迁移与事务——“数据库的版本核爆”
4.1 自动迁移配置
// 使用PowerShell执行迁移
// 添加迁移
Add-Migration "InitialCreate" -Context SchoolDbContext
// 更新数据库
Update-Database -Context SchoolDbContext
// 自定义迁移(保留历史数据)
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.Sql("UPDATE Students SET GPA = 4.0 WHERE Id = 1");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.Sql("UPDATE Students SET GPA = 0 WHERE Id = 1");
}
4.2 分布式事务
// 使用TransactionScope实现跨数据库事务
using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
using (var context1 = new SchoolDbContext())
using (var context2 = new OrderDbContext())
{
// 操作SchoolDbContext
context1.Students.Add(new Student { Name = "Alice" });
context1.SaveChanges();
// 操作OrderDbContext
context2.Customers.Add(new Customer { Name = "Alice" });
context2.SaveChanges();
scope.Complete(); // 提交事务
}
}
4.3 性能优化技巧
// 使用EF Profiler监控查询
public class EfProfilerMiddleware
{
public async Task Invoke(HttpContext context)
{
using (var profiler = new Profiler())
{
await profiler.ProfileAsync(context);
}
}
}
// 使用内存缓存(Redis)
public class EfCacheInterceptor : DbCommandInterceptor
{
public override InterceptionResult ReaderExecuting(
DbCommand command,
CommandEventData eventData,
InterceptionResult result)
{
var cacheKey = $"EF_{command.CommandText}";
if (RedisCache.Exists(cacheKey))
{
// 从缓存返回数据
return InterceptionResult.Stop;
}
return result;
}
}
🔥 模块5:实战案例——电商系统的“全栈核武器级”方案
5.1 需求分析
- 复杂关系:商品、订单、用户、支付
- 高并发:秒杀场景的乐观锁
- 多数据库:主库与读库分离
5.2 核心代码实现
// 商品实体(带乐观锁)
public class Product : IEntity
{
public int ProductId { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public int Stock { get; set; }
public byte[] RowVersion { get; set; } // 乐观锁版本号
// 多对多:商品与分类
public ICollection<Category> Categories { get; set; } = new List<Category>();
}
// 订单实体(带复杂外键)
public class Order
{
public int OrderId { get; set; }
public DateTime OrderDate { get; set; }
public int CustomerId { get; set; }
public Customer Customer { get; set; }
// 订单项(复合主键)
public ICollection<OrderItem> Items { get; set; } = new List<OrderItem>();
}
// 订单项(复合主键配置)
public class OrderItem
{
public int OrderId { get; set; }
public int ProductId { get; set; }
public int Quantity { get; set; }
public decimal UnitPrice { get; set; }
// 导航属性
public Order Order { get; set; }
public Product Product { get; set; }
}
// DbContext配置(分库分表)
public class ECommerceDbContext : DbContext
{
public DbSet<Product> Products { get; set; }
public DbSet<Order> Orders { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// 分表策略(按订单年份)
modelBuilder.Entity<Order>()
.ToTable($"Orders_{DateTime.Now.Year}");
// 复合主键配置
modelBuilder.Entity<OrderItem>()
.HasKey(oi => new { oi.OrderId, oi.ProductId });
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(
"Server=master.sql;Database=ECommerce;Trusted_Connection=True;",
sqlOptions => sqlOptions.CommandTimeout(30)
);
}
}
// 乐观锁实现(秒杀场景)
public async Task<bool> PurchaseProduct(int productId, int quantity)
{
var product = await dbContext.Products
.AsNoTracking() // 禁用缓存
.FirstOrDefaultAsync(p => p.ProductId == productId);
if (product.Stock < quantity)
return false;
var entry = dbContext.Attach(product);
entry.State = EntityState.Modified;
// 设置乐观锁条件
entry.Property(p => p.RowVersion).IsModified = true;
entry.Property(p => p.Stock).CurrentValue = product.Stock - quantity;
try
{
await dbContext.SaveChangesAsync();
return true;
}
catch (DbUpdateConcurrencyException)
{
return false;
}
}
🔑 核心技巧:EF的“核爆”优化
6.1 性能优化
// 使用AsSplitQuery解决Cartesian Product
var orders = dbContext.Orders
.Include(o => o.Customer)
.Include(o => o.Items.Select(i => i.Product))
.AsSplitQuery() // 分拆查询
.ToList();
// 使用EF Core 8的跟踪器优化
var tracker = dbContext.ChangeTracker;
tracker.AutoDetectChangesEnabled = false; // 禁用自动检测
6.2 NoSQL集成
// 使用EF Core与MongoDB
public class ProductContext : DbContext
{
public DbSet<Product> Products { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseMongoDB(
"mongodb://localhost:27017",
b => b.DatabaseName = "ECommerce"
);
}
}
6.3 跨平台迁移
// 迁移到MySQL的自定义迁移
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.Sql("ALTER TABLE Students ENGINE = InnoDB;");
}
🌐 模块6:跨框架集成
6.1 与ASP.NET Core集成
// Startup.cs配置
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
// 控制器中使用
public class ProductsController : ControllerBase
{
private readonly ApplicationDbContext _context;
public ProductsController(ApplicationDbContext context)
{
_context = context;
}
[HttpGet]
public async Task<IActionResult> GetProducts()
{
return Ok(await _context.Products.ToListAsync());
}
}
6.2 与Blazor集成
// Blazor组件
@page "/products"
@inject ApplicationDbContext Context
<ul>
@foreach (var product in Products)
{
<li>@product.Name - @product.Price</li>
}
</ul>
@code {
private List<Product> Products { get; set; }
protected override async Task OnInitializedAsync()
{
Products = await Context.Products.ToListAsync();
}
}
🌌 方案对比与选择指南
模块 | 技术选型 | 性能 | 适用场景 | 扩展性 |
---|---|---|---|---|
ORM映射 | Code First + Fluent API | 高 | 复杂关系型数据库 | 支持多对多/继承 |
查询语言 | LINQ + 原始SQL | 中高 | 复杂查询与性能敏感场景 | 支持并行查询 |
数据上下文 | 分层DbContext + 分库分表 | 极高 | 多租户/高并发系统 | 支持分布式事务 |
迁移 | 自动迁移 + 定制脚本 | 中 | 版本控制与历史回滚 | 支持多数据库 |
事务 | TransactionScope | 高 | 跨数据库/服务事务 | 支持分布式系统 |
通过 六大核心模块,你现在能:
- ORM映射:用注解+Fluent API实现复杂关系
- 查询语言:LINQ的“时空穿越”与性能优化
- 数据上下文:DbContext的分库分表与事务管理
- 迁移与版本控制:自动迁移与分布式事务
- 全栈实战:电商系统的“核武器级”解决方案
1. 电商系统核心代码
// 商品控制器(RESTful API)
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
private readonly ECommerceDbContext _context;
public ProductsController(ECommerceDbContext context)
{
_context = context;
}
[HttpGet]
public async Task<ActionResult<IEnumerable<Product>>> GetProducts()
{
return await _context.Products
.Include(p => p.Categories)
.ToListAsync();
}
[HttpPost]
public async Task<ActionResult<Product>> CreateProduct(Product product)
{
_context.Products.Add(product);
await _context.SaveChangesAsync();
return CreatedAtAction(nameof(GetProduct), new { id = product.ProductId }, product);
}
}
2. 分布式事务示例
// 使用分布式事务协调器
public class TransactionService
{
public async Task ExecuteTransaction(Func<Task> action)
{
using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
try
{
await action();
scope.Complete();
}
catch
{
scope.Dispose();
throw;
}
}
}
}
3. 性能监控工具集成
// 使用MiniProfiler
public class Startup
{
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseMiniProfiler();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}