当前位置: 首页 > news >正文

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的核心价值
  1. 提高开发效率:减少约30-40%的数据访问层代码量
  2. 降低技术门槛:无需精通SQL即可实现复杂数据操作
  3. 增强可维护性:强类型模型减少运行时错误
  4. 数据库无关性:支持多种数据库系统迁移

1.2 EF架构设计

1.2.1 整体架构分层
[应用程序层]|
[LINQ查询]|
[Entity Framework]|       |
[概念模型]  [存储模型]|       |
[映射层]|
[ADO.NET数据提供程序]|
[数据库]
1.2.2 核心组件详解
  1. EDM (Entity Data Model)

    • CSDL (Conceptual Schema Definition Language): 概念层定义
    • SSDL (Storage Schema Definition Language): 存储层定义
    • MSL (Mapping Specification Language): 映射规范
  2. DbContext

    • 工作单元和仓库模式的实现
    • 包含的主要属性:
      • DbSet: 实体集合
      • ChangeTracker: 变更跟踪器
      • Configuration: 配置选项
  3. LINQ提供程序

    • 将LINQ查询转换为SQL语句
    • 支持查询语法和方法语法

第二部分:EF开发模式详解

2.1 Database First开发模式

Database First是从现有数据库生成模型的方法,适合已有成熟数据库结构的项目。

2.1.1 实施步骤
  1. 在Visual Studio中添加"ADO.NET实体数据模型"
  2. 选择"从数据库生成"
  3. 配置数据库连接
  4. 选择要包含的表、视图和存储过程
  5. 完成模型生成
2.1.2 优缺点分析

优点

  • 快速对接现有数据库
  • 可视化设计器便于理解数据结构
  • 自动生成实体类和上下文

缺点

  • 模型更新需重新生成
  • 自定义逻辑需扩展部分类
  • 与数据库耦合度较高

2.2 Model First开发模式

Model First允许先设计概念模型,再生成数据库结构。

2.2.1 工作流程
  1. 在EDM设计器中创建实体和关系
  2. 设置实体属性和关联
  3. 生成数据库脚本
  4. 执行脚本创建物理数据库
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 配置方式
  1. 数据注解

    [Table("tbl_Products")]
    public class Product
    {[Key][DatabaseGenerated(DatabaseGeneratedOption.Identity)]public int ProductId { get; set; }[Required][MaxLength(100)]public string Name { get; set; }
    }
    
  2. 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 迁移机制
  1. 启用迁移:

    Enable-Migrations
    
  2. 创建迁移:

    Add-Migration InitialCreate
    
  3. 更新数据库:

    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 加载相关数据
  1. 预先加载(Eager Loading)

    var orders = context.Orders.Include(o => o.Customer).Include(o => o.OrderDetails).ThenInclude(od => od.Product).ToList();
    
  2. 显式加载(Explicit Loading)

    var order = context.Orders.Find(1);
    context.Entry(order).Collection(o => o.OrderDetails).Load();
    
  3. 延迟加载(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 事务管理
  1. 默认事务

    using (var transaction = context.Database.BeginTransaction())
    {try{// 操作1// 操作2context.SaveChanges();transaction.Commit();}catch{transaction.Rollback();}
    }
    
  2. 跨上下文事务

    using (var scope = new TransactionScope())
    {// 上下文1操作// 上下文2操作scope.Complete();
    }
    

3.3 性能优化

3.3.1 查询优化技巧
  1. 选择性加载字段

    var productNames = context.Products.Select(p => new { p.Id, p.Name }).ToList();
    
  2. 批量操作

    // EF Core 5.0+ 支持
    context.Products.AddRange(productsList);
    await context.SaveChangesAsync();
    
  3. 禁用变更跟踪

    var products = context.Products.AsNoTracking().ToList();
    
3.3.2 高级优化策略
  1. 编译查询

    private static readonly Func<MyContext, int, Product> _productById =EF.CompileQuery((MyContext db, int id) =>db.Products.FirstOrDefault(p => p.Id == id));
    
  2. 批处理语句

    • 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 架构设计建议

  1. 分层架构

    • 表现层
    • 应用层
    • 领域层
    • 基础设施层(包含EF实现)
  2. 仓储模式实现

    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 性能调优指南

  1. 连接池配置

    services.AddDbContextPool<MyContext>(options => options.UseSqlServer(connectionString), poolSize: 128);
    
  2. 批处理优化

    • 合理设置SaveChanges批处理大小
    • 考虑使用BulkExtensions进行大规模操作

6.3 安全注意事项

  1. SQL注入防护

    • 始终使用参数化查询
    • 避免直接拼接SQL字符串
  2. 敏感数据保护

    • 加密存储敏感字段
    • 实现数据访问审计

第七部分: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){// 领域逻辑}
}
http://www.dtcms.com/a/286757.html

相关文章:

  • 数据查找 二叉查找树
  • 网关-微服务网关实现
  • AI大模型打造金融智能信审助手04.七大金融监管相关政策
  • 活动图描述场景
  • CityEngine自动化建模
  • 代理模式及优化
  • 代码随想录day38dp6
  • STM32-第七节-TIM定时器-3(输入捕获)
  • 全排列 II
  • C#通过HslCommunication连接西门子PLC1200,并防止数据跳动的通用方法
  • 反序列化漏洞2-魔术方法介绍与演示
  • 怎么自己搭建云手机
  • http与https的主要区别是什么?
  • java数据类型
  • 锂电池无线充电电路设计
  • 零碳园区势在必行!安科瑞EMS3.0助力园区低碳智慧升级
  • Excel导出实战:从入门到精通 - 构建专业级数据报表的完整指南
  • 如何使用 Jackson 处理 YAML
  • AE电源MDX 5K 10K 15K 20K 25K 30K手侧操作使用说明
  • 拉普拉斯方程傅里叶积分解法
  • @Primary 是做什么的?
  • CAD 约束求解:核心技术原理、流程及主流框架快速解析
  • A33-vstar笔记及资料分享:搭建交叉编译环境
  • 动态规划 + DFS + 记忆化!Swift 解 LeetCode 329 的实战笔记
  • 实战指南|智慧无人机安防系统搭建全流程解析
  • 记录DataGrip 2025.1.3破解失败后,无法重启问题修复
  • centos7安装MySQL8.4手册
  • Hive数据仓库工具
  • 甲状腺结节TI-RADS分类的多目标分类头任务深度学习模型评估报告
  • go语言学习之包