Entity Framework (EF) 深度解析
文章目录
- 第一部分:Entity Framework 基础概念与架构
- 1.1 Entity Framework 简介
- 1.1.1 EF的发展历程
- 1.1.2 EF的核心价值
- 1.2 EF架构设计
- 1.2.1 整体架构分层
- 1.2.2 核心组件详解
- 第二部分:EF开发模式详解
- 2.1 Database First开发模式
- 2.1.1 实施步骤
- 2.1.2 优缺点分析
- 2.2 Model First开发模式
- 2.2.1 工作流程
- 2.2.2 最佳实践
- 2.3 Code First开发模式
- 2.3.1 基础实现
- 2.3.2 配置方式
- 2.3.3 迁移机制
- 第三部分:EF核心功能深入解析
- 3.1 查询数据
- 3.1.1 基本查询操作
- 3.1.2 加载相关数据
- 3.1.3 原生SQL查询
- 3.2 保存数据
- 3.2.1 基本操作
- 3.2.2 事务管理
- 3.3 性能优化
- 3.3.1 查询优化技巧
- 3.3.2 高级优化策略
- 第四部分:EF高级主题
- 4.1 复杂类型和值转换
- 4.1.1 复杂类型(Owned Entities)
- 4.1.2 值转换器
- 4.2 拦截器和事件
- 4.2.1 拦截器示例
- 4.2.2 事件处理
- 4.3 多租户实现
- 第五部分:EF Core 特有功能
- 5.1 全局查询过滤器
- 5.2 表拆分
- 5.3 并发控制
- 第六部分:EF最佳实践
- 6.1 架构设计建议
- 6.2 性能调优指南
- 6.3 安全注意事项
- 第七部分:EF与其他技术集成
- 7.1 与ASP.NET Core集成
- 7.2 DDD实现模式

第一部分:Entity Framework 基础概念与架构
1.1 Entity Framework 简介
Entity Framework (EF) 是微软为.NET应用程序开发提供的一个开源对象关系映射(O/RM)框架。作为ADO.NET的增强版本,它使开发人员能够以面向对象的方式处理数据,而无需过多关注底层数据库结构。
1.1.1 EF的发展历程
- EF 3.5 (2008年): 首个版本,随.NET Framework 3.5 SP1发布
- EF 4.0 (2010年): 引入模型优先开发、延迟加载等关键功能
- EF 4.1 (2011年): 推出DbContext API和Code First方法
- EF 5.0 (2012年): 性能优化,支持枚举类型
- EF 6.x (2013-2015): 独立发展,增加异步操作、拦截器等
- EF Core 1.0 (2016年): 完全重写,跨平台支持
- EF Core 最新版本: 持续演进,功能不断增强
1.1.2 EF的核心价值
- 提高开发效率:减少约30-40%的数据访问层代码量
- 降低技术门槛:无需精通SQL即可实现复杂数据操作
- 增强可维护性:强类型模型减少运行时错误
- 数据库无关性:支持多种数据库系统迁移
1.2 EF架构设计
1.2.1 整体架构分层
[应用程序层]|
[LINQ查询]|
[Entity Framework]| |
[概念模型] [存储模型]| |
[映射层]|
[ADO.NET数据提供程序]|
[数据库]
1.2.2 核心组件详解
-
EDM (Entity Data Model)
- CSDL (Conceptual Schema Definition Language): 概念层定义
- SSDL (Storage Schema Definition Language): 存储层定义
- MSL (Mapping Specification Language): 映射规范
-
DbContext
- 工作单元和仓库模式的实现
- 包含的主要属性:
- DbSet: 实体集合
- ChangeTracker: 变更跟踪器
- Configuration: 配置选项
-
LINQ提供程序
- 将LINQ查询转换为SQL语句
- 支持查询语法和方法语法
第二部分:EF开发模式详解
2.1 Database First开发模式
Database First是从现有数据库生成模型的方法,适合已有成熟数据库结构的项目。
2.1.1 实施步骤
- 在Visual Studio中添加"ADO.NET实体数据模型"
- 选择"从数据库生成"
- 配置数据库连接
- 选择要包含的表、视图和存储过程
- 完成模型生成
2.1.2 优缺点分析
优点:
- 快速对接现有数据库
- 可视化设计器便于理解数据结构
- 自动生成实体类和上下文
缺点:
- 模型更新需重新生成
- 自定义逻辑需扩展部分类
- 与数据库耦合度较高
2.2 Model First开发模式
Model First允许先设计概念模型,再生成数据库结构。
2.2.1 工作流程
- 在EDM设计器中创建实体和关系
- 设置实体属性和关联
- 生成数据库脚本
- 执行脚本创建物理数据库
2.2.2 最佳实践
- 合理使用继承策略(TPH, TPT, TPC)
- 正确配置导航属性
- 优化生成的DDL脚本
2.3 Code First开发模式
Code First是目前最流行的EF开发方式,完全通过代码定义模型。
2.3.1 基础实现
public class Product
{public int Id { get; set; }public string Name { get; set; }public decimal Price { get; set; }
}public class StoreContext : DbContext
{public DbSet<Product> Products { get; set; }
}
2.3.2 配置方式
-
数据注解
[Table("tbl_Products")] public class Product {[Key][DatabaseGenerated(DatabaseGeneratedOption.Identity)]public int ProductId { get; set; }[Required][MaxLength(100)]public string Name { get; set; } }
-
Fluent API
protected override void OnModelCreating(ModelBuilder modelBuilder) {modelBuilder.Entity<Product>().ToTable("tbl_Products").HasKey(p => p.ProductId);modelBuilder.Entity<Product>().Property(p => p.Name).IsRequired().HasMaxLength(100); }
2.3.3 迁移机制
-
启用迁移:
Enable-Migrations
-
创建迁移:
Add-Migration InitialCreate
-
更新数据库:
Update-Database
第三部分:EF核心功能深入解析
3.1 查询数据
3.1.1 基本查询操作
// 获取所有产品
var products = context.Products.ToList();// 条件查询
var expensiveProducts = context.Products.Where(p => p.Price > 100).OrderBy(p => p.Name).ToList();
3.1.2 加载相关数据
-
预先加载(Eager Loading)
var orders = context.Orders.Include(o => o.Customer).Include(o => o.OrderDetails).ThenInclude(od => od.Product).ToList();
-
显式加载(Explicit Loading)
var order = context.Orders.Find(1); context.Entry(order).Collection(o => o.OrderDetails).Load();
-
延迟加载(Lazy Loading)
- 需安装Microsoft.EntityFrameworkCore.Proxies包
- 配置:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) {optionsBuilder.UseLazyLoadingProxies(); }
3.1.3 原生SQL查询
var products = context.Products.FromSqlRaw("SELECT * FROM Products WHERE Price > {0}", 50).ToList();
3.2 保存数据
3.2.1 基本操作
// 添加
var newProduct = new Product { Name = "New Product", Price = 99.99m };
context.Products.Add(newProduct);// 更新
var product = context.Products.Find(1);
product.Price = 109.99m;// 删除
var productToDelete = context.Products.Find(2);
context.Products.Remove(productToDelete);// 保存
context.SaveChanges();
3.2.2 事务管理
-
默认事务
using (var transaction = context.Database.BeginTransaction()) {try{// 操作1// 操作2context.SaveChanges();transaction.Commit();}catch{transaction.Rollback();} }
-
跨上下文事务
using (var scope = new TransactionScope()) {// 上下文1操作// 上下文2操作scope.Complete(); }
3.3 性能优化
3.3.1 查询优化技巧
-
选择性加载字段
var productNames = context.Products.Select(p => new { p.Id, p.Name }).ToList();
-
批量操作
// EF Core 5.0+ 支持 context.Products.AddRange(productsList); await context.SaveChangesAsync();
-
禁用变更跟踪
var products = context.Products.AsNoTracking().ToList();
3.3.2 高级优化策略
-
编译查询
private static readonly Func<MyContext, int, Product> _productById =EF.CompileQuery((MyContext db, int id) =>db.Products.FirstOrDefault(p => p.Id == id));
-
批处理语句
- EF Core默认将多个操作合并为单个批处理
- 可配置批处理大小:
optionsBuilder.UseSqlServer(connectionString,options => options.MaxBatchSize(100));
第四部分:EF高级主题
4.1 复杂类型和值转换
4.1.1 复杂类型(Owned Entities)
modelBuilder.Entity<Order>().OwnsOne(o => o.ShippingAddress,sa =>{sa.Property(p => p.Street).HasColumnName("ShippingStreet");sa.Property(p => p.City).HasColumnName("ShippingCity");});
4.1.2 值转换器
modelBuilder.Entity<Product>().Property(p => p.Price).HasConversion(v => v.ToString(),v => decimal.Parse(v));
4.2 拦截器和事件
4.2.1 拦截器示例
public class MyInterceptor : DbCommandInterceptor
{public override InterceptionResult<DbDataReader> ReaderExecuting(DbCommand command,CommandEventData eventData,InterceptionResult<DbDataReader> result){// 修改或记录命令return result;}
}
4.2.2 事件处理
context.SavingChanges += (sender, args) =>
{var entries = context.ChangeTracker.Entries();foreach (var entry in entries){// 预处理实体}
};
4.3 多租户实现
modelBuilder.Entity<Product>().HasQueryFilter(p => p.TenantId == _tenantId);
第五部分:EF Core 特有功能
5.1 全局查询过滤器
modelBuilder.Entity<Blog>().HasQueryFilter(b => !b.IsDeleted);
5.2 表拆分
modelBuilder.Entity<Order>(eb =>
{eb.ToTable("Orders");eb.Property(o => o.Status).HasColumnName("Status");eb.OwnsOne(o => o.Details, odb =>{odb.ToTable("OrderDetails");odb.Property(od => od.Notes).HasColumnName("Notes");});
});
5.3 并发控制
modelBuilder.Entity<Person>().Property(p => p.LastName).IsConcurrencyToken();
第六部分:EF最佳实践
6.1 架构设计建议
-
分层架构
- 表现层
- 应用层
- 领域层
- 基础设施层(包含EF实现)
-
仓储模式实现
public interface IRepository<T> where T : class {IQueryable<T> GetAll();Task<T> GetByIdAsync(int id);void Add(T entity);void Update(T entity);void Delete(T entity); }
6.2 性能调优指南
-
连接池配置
services.AddDbContextPool<MyContext>(options => options.UseSqlServer(connectionString), poolSize: 128);
-
批处理优化
- 合理设置SaveChanges批处理大小
- 考虑使用BulkExtensions进行大规模操作
6.3 安全注意事项
-
SQL注入防护
- 始终使用参数化查询
- 避免直接拼接SQL字符串
-
敏感数据保护
- 加密存储敏感字段
- 实现数据访问审计
第七部分:EF与其他技术集成
7.1 与ASP.NET Core集成
public void ConfigureServices(IServiceCollection services)
{services.AddDbContext<MyContext>(options =>options.UseSqlServer(Configuration.GetConnectionString("Default")));services.AddControllers();
}
7.2 DDD实现模式
public class Order : IAggregateRoot
{private readonly List<OrderItem> _items = new List<OrderItem>();public IReadOnlyCollection<OrderItem> Items => _items.AsReadOnly();public void AddItem(Product product, int quantity){// 领域逻辑}
}