.NET Core 数据库ORM框架用法简述

.NET Core ORM框架用法简述

一、主流.NET Core ORM框架概述

在.NET Core生态系统中,主流的ORM(Object-Relational Mapping)框架包括:

  1. ​Entity Framework Core (EF Core)​​ - 微软官方推出的ORM框架
  2. ​Dapper​​ - 轻量级微ORM
  3. ​Npgsql.EntityFrameworkCore.PostgreSQL​​ - PostgreSQL专用EF Core提供程序
  4. ​Pomelo.EntityFrameworkCore.MySql​​ - MySQL专用EF Core提供程序
  5. ​LINQ to DB​​ - 高性能ORM

本文重点介绍最常用的EF Core和Dapper。

二、Entity Framework Core (EF Core) 使用指南

1. 安装与配置

​安装NuGet包​​:

 
dotnet add package Microsoft.EntityFrameworkCore
dotnet add package Microsoft.EntityFrameworkCore.SqlServer # SQL Server提供程序
# 或其他数据库提供程序

​DbContext配置​​:

 
public class AppDbContext : DbContext
{public DbSet<User> Users { get; set; }public DbSet<Order> Orders { get; set; }protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder){optionsBuilder.UseSqlServer("Server=.;Database=MyApp;Trusted_Connection=True;");}
}

​依赖注入配置​​(推荐):

 
// Startup.cs或Program.cs
builder.Services.AddDbContext<AppDbContext>(options =>options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));

2. 数据模型定义

​实体类​​:

 
public class User
{public int Id { get; set; }public string Name { get; set; }public DateTime BirthDate { get; set; }// 导航属性public ICollection<Order> Orders { get; set; }
}public class Order
{public int Id { get; set; }public decimal Amount { get; set; }public DateTime OrderDate { get; set; }// 外键和导航属性public int UserId { get; set; }public User User { get; set; }
}

​Fluent API配置​​:

 
protected override void OnModelCreating(ModelBuilder modelBuilder)
{modelBuilder.Entity<User>().Property(u => u.Name).IsRequired().HasMaxLength(50);modelBuilder.Entity<Order>().HasOne(o => o.User).WithMany(u => u.Orders).HasForeignKey(o => o.UserId);
}

3. CRUD操作

​添加数据​​:

 
using (var context = new AppDbContext())
{var user = new User { Name = "张三", BirthDate = new DateTime(1990, 1, 1) };context.Users.Add(user);context.SaveChanges();
}

​查询数据​​:

 
// 简单查询
var users = context.Users.ToList();// 条件查询
var activeUsers = context.Users.Where(u => u.Name.Contains("张")).OrderBy(u => u.BirthDate).ToList();// 投影查询
var userNames = context.Users.Select(u => new { u.Id, u.Name }).ToList();

​更新数据​​:

 
using (var context = new AppDbContext())
{var user = context.Users.Find(1);if (user != null){user.Name = "李四";context.SaveChanges();}
}

​删除数据​​:

 
using (var context = new AppDbContext())
{var user = context.Users.Find(1);if (user != null){context.Users.Remove(user);context.SaveChanges();}
}

4. 高级功能

​异步操作​​:

 
var user = await context.Users.FindAsync(1);
var users = await context.Users.Where(u => u.Name.Contains("张")).ToListAsync();

​事务处理​​:

 
using (var transaction = await context.Database.BeginTransactionAsync())
{try{// 执行多个操作await context.SaveChangesAsync();await transaction.CommitAsync();}catch{await transaction.RollbackAsync();throw;}
}

​迁移管理​​:

 
# 添加迁移
dotnet ef migrations add InitialCreate# 更新数据库
dotnet ef database update# 回滚迁移
dotnet ef database update PreviousMigration

三、Dapper使用指南

1. 安装与配置

​安装NuGet包​​:

 
dotnet add package Dapper
dotnet add package System.Data.SqlClient # SQL Server提供程序

​基本使用​​:

 
using var connection = new SqlConnection("Server=.;Database=MyApp;Trusted_Connection=True;");
connection.Open();

2. CRUD操作

​查询数据​​:

 
var users = connection.Query<User>("SELECT * FROM Users WHERE Name LIKE @Name", new { Name = "%张%" });var user = connection.QueryFirstOrDefault<User>("SELECT * FROM Users WHERE Id = @Id", new { Id = 1 });

​插入数据​​:

 
var id = connection.QuerySingle<int>("INSERT INTO Users (Name, BirthDate) VALUES (@Name, @BirthDate); SELECT SCOPE_IDENTITY();",new { Name = "张三", BirthDate = DateTime.Now });

​更新数据​​:

 
var affectedRows = connection.Execute("UPDATE Users SET Name = @Name WHERE Id = @Id",new { Name = "李四", Id = 1 });

​删除数据​​:

 
var deletedRows = connection.Execute("DELETE FROM Users WHERE Id = @Id", new { Id = 1 });

3. 高级功能

​存储过程调用​​:

 
var users = connection.Query<User>("dbo.GetUsersByAgeRange", new { MinAge = 18, MaxAge = 30 },commandType: CommandType.StoredProcedure);

​多结果集处理​​:

 
using (var multi = connection.QueryMultiple("SELECT * FROM Users; SELECT * FROM Orders", commandType: CommandType.Text))
{var users = multi.Read<User>().ToList();var orders = multi.Read<Order>().ToList();
}

​动态参数​​:

 
var sql = "SELECT * FROM Users WHERE 1=1";
var parameters = new DynamicParameters();
if (!string.IsNullOrEmpty(name))
{sql += " AND Name = @Name";parameters.Add("Name", name);
}
if (minAge.HasValue)
{sql += " AND Age >= @MinAge";parameters.Add("MinAge", minAge.Value);
}var users = connection.Query<User>(sql, parameters);

四、EF Core与Dapper对比

特性EF CoreDapper
​性能​中等(有ORM开销)高(接近原生SQL)
​学习曲线​较陡峭(需理解LINQ、EF概念)平缓(SQL知识即可)
​功能丰富度​高(迁移、跟踪、变更检测等)低(仅数据访问)
​适用场景​复杂业务、快速开发高性能需求、复杂SQL
​异步支持​原生支持需手动实现
​事务管理​内置支持需手动实现
​缓存​一级缓存无内置缓存

五、选择建议

  1. ​选择EF Core当​​:

    • 需要快速开发CRUD应用
    • 团队熟悉ORM概念
    • 需要数据库迁移功能
    • 项目需要频繁变更数据模型
  2. ​选择Dapper当​​:

    • 需要极致性能
    • 执行复杂SQL查询
    • 已有成熟的SQL知识
    • 项目以读为主,写操作较少

六、最佳实践

EF Core最佳实践

  1. ​合理使用延迟加载​​:

     
    // 禁用延迟加载(推荐)
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {optionsBuilder.UseLazyLoadingProxies(false);
    }
  2. ​批量操作优化​​:

    // 使用AddRange代替多个Add
    context.Users.AddRange(usersList);// 对于大量数据,考虑分批处理
    foreach (var batch in usersList.Batch(500))
    {context.Users.AddRange(batch);context.SaveChanges();
    }
  3. ​避免N+1查询​​:

    // 不好的做法(会导致N+1)
    var users = context.Users.ToList();
    foreach (var user in users)
    {var orders = context.Orders.Where(o => o.UserId == user.Id).ToList();
    }// 好的做法(预加载)
    var users = context.Users.Include(u => u.Orders).ToList();

Dapper最佳实践

  1. ​使用参数化查询​​:

     
    // 安全的方式
    connection.Query<User>("SELECT * FROM Users WHERE Name = @Name", new { Name = userInput });// 避免拼接SQL字符串(有SQL注入风险)
    // connection.Query<User>($"SELECT * FROM Users WHERE Name = '{userInput}'");
  2. ​连接管理​​:

     
    // 使用using确保连接释放
    using (var connection = new SqlConnection(connectionString))
    {connection.Open();// 执行操作
    }
  3. ​存储过程调用​​:

     
    var result = connection.QueryFirstOrDefault<int>("dbo.GetUserCountByRole",new { RoleId = roleId },commandType: CommandType.StoredProcedure);

七、性能优化技巧

EF Core性能优化

  1. ​启用查询缓存​​:

    services.AddDbContext<AppDbContext>(options =>options.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking).UseSqlServer(connectionString));
  2. ​使用AsNoTracking​​:

    // 只读场景使用
    var users = context.Users.AsNoTracking().ToList();
  3. ​投影查询​​:

    // 只查询需要的字段
    var userDtos = context.Users.Select(u => new UserDto { Id = u.Id, Name = u.Name }).ToList();

Dapper性能优化

  1. ​使用ExecuteScalar代替QueryFirstOrDefault​​:

    // 获取单个值
    var count = connection.ExecuteScalar<int>("SELECT COUNT(*) FROM Users");
  2. ​使用动态类型​​:

    // 当不需要强类型时
    var result = connection.Query("SELECT * FROM Users").FirstOrDefault();
  3. ​连接池配置​​:

    // 在连接字符串中配置
    "Server=.;Database=MyApp;User Id=user;Password=pass;Max Pool Size=100;"

八、常见问题解决

EF Core常见问题

  1. ​N+1查询问题​​:

    • 使用IncludeThenInclude预加载
    • 使用Select投影查询
  2. ​性能下降​​:

    • 检查生成的SQL(使用日志)
    • 考虑禁用变更跟踪(AsNoTracking)
    • 优化数据库索引
  3. ​迁移冲突​​:

    • 使用dotnet ef migrations remove回滚
    • 手动合并迁移文件

Dapper常见问题

  1. ​SQL注入风险​​:

    • 始终使用参数化查询
    • 避免字符串拼接SQL
  2. ​连接泄漏​​:

    • 确保使用using语句
    • 实现IDisposable模式管理连接
  3. ​结果映射错误​​:

    • 检查列名与属性名匹配
    • 使用Query<T>时确保T有默认构造函数

九、工具与扩展

EF Core工具

  1. ​EF Core Power Tools​​:

    • 可视化查看数据库模型
    • 快速生成实体类
    • 执行数据库比较
  2. ​Entity Framework Core Profiler​​:

    • 分析EF Core生成的SQL
    • 性能监控

Dapper扩展

  1. ​Dapper.Contrib​​:

    • 添加简单的CRUD扩展方法
    connection.Insert(user);
    connection.Update(user);
  2. ​Dapper.FluentMap​​:

    • 配置实体到表的映射
    FluentMapper.Initialize(config =>
    {config.AddMap(new UserMap());
    });
  3. ​DapperQueryBuilder​​:

    • 构建安全动态SQL
    var query = connection.QueryBuilder($"SELECT * FROM Users WHERE 1=1");
    if (name != null) query.Where("Name = @Name", new { Name = name });
    var users = query.Query<User>();

十、总结与建议

  1. ​EF Core适合​​:

    • 快速开发的企业应用
    • 需要数据库迁移的项目
    • 团队熟悉ORM的情况
  2. ​Dapper适合​​:

    • 高性能要求的微服务
    • 复杂SQL查询场景
    • 已有成熟SQL知识的项目
  3. ​混合使用策略​​:

    • 主框架使用EF Core
    • 性能关键部分使用Dapper
    // 在EF Core项目中使用Dapper
    public class UserRepository : IUserRepository
    {private readonly AppDbContext _context;private readonly IDbConnection _dapperConnection;public UserRepository(AppDbContext context, IDbConnection dapperConnection){_context = context;_dapperConnection = dapperConnection;}public User GetById(int id){// 使用EF Corereturn _context.Users.Find(id);}public IEnumerable<User> GetActiveUsers(){// 使用Dapper执行复杂查询return _dapperConnection.Query<User>("SELECT * FROM Users WHERE IsActive = 1");}
    }

通过合理选择ORM框架并遵循最佳实践,可以显著提高.NET Core应用程序的开发效率和性能表现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/81078.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

halcon打开图形窗口

1、dev_open_window 参数如下&#xff1a; 1&#xff09;Row(输入参数) y方向上&#xff0c;图形窗口距离左上角顶端的像素个数 2&#xff09;Column(输入参数) x方向上&#xff0c;距离左上角左边的像素个数 3&#xff09;Width(输入参数) 图形窗口宽度 4&#xff09;He…

2025东三省D题深圳杯D题数学建模挑战赛数模思路代码文章教学

完整内容请看文章最下面的推广群 一、问题一&#xff1a;混合STR图谱中贡献者人数判定 问题解析 给定混合STR图谱&#xff0c;识别其中的真实贡献者人数是后续基因型分离与个体识别的前提。图谱中每个位点最多应出现2n个峰&#xff08;n为人数&#xff09;&#xff0c;但由…

iView Table 组件跨页选择功能实现文档

iView Table 组件跨页选择功能实现文档 功能概述 实现基于 iView Table 组件的多选功能&#xff0c;支持以下特性&#xff1a; ✅ 跨页数据持久化选择✅ 当前页全选/取消全选✅ 自动同步选中状态显示✅ 分页切换状态保持✅ 高性能大数据量支持 实现方案 技术栈 iView UI 4…

家庭服务器IPV6搭建无限邮箱系统指南

qq邮箱操作 // 邮箱配置信息 // 注意&#xff1a;使用QQ邮箱需要先开启IMAP服务并获取授权码 // 设置方法&#xff1a;登录QQ邮箱 -> 设置 -> 账户 -> 开启IMAP/SMTP服务 -> 生成授权码 服务器操作 fetchmail 同步QQ邮箱 nginx搭建web显示本地同步过来的邮箱 ssh…

Tauri v1 与 v2 配置对比

本文档对比 Tauri v1 和 v2 版本的配置结构和内容差异&#xff0c;帮助开发者了解版本变更并进行迁移。 配置结构变化 v1 配置结构 {"package": { ... },"tauri": { "allowlist": { ... },"bundle": { ... },"security":…

对js的Date二次封装,继承了原Date的所有方法,增加了自己扩展的方法,可以实现任意时间往前往后推算多少小时、多少天、多少周、多少月;

封装js时间工具 概述 该方法继承了 js 中 Date的所有方法&#xff1b;同时扩展了一部分自用方法&#xff1a; 1、任意时间 往前推多少小时&#xff0c;天&#xff0c;月&#xff0c;周&#xff1b;参数1、2必填&#xff0c;参数3可选beforeDate(num,formatter,dateVal); befo…

TimeDistill:通过跨架构蒸馏的MLP高效长期时间序列预测

原文地址&#xff1a;https://arxiv.org/abs/2502.15016 发表会议&#xff1a;暂定&#xff08;但是Star很高&#xff09; 代码地址&#xff1a;无 作者&#xff1a;Juntong Ni &#xff08;倪浚桐&#xff09;, Zewen Liu &#xff08;刘泽文&#xff09;, Shiyu Wang&…

DeepSeek最新大模型发布-DeepSeek-Prover-V2-671B

2025 年 4 月 30 日&#xff0c;DeepSeek 开源了新模型 DeepSeek-Prover-V2-671B&#xff0c;该模型聚焦数学定理证明任务&#xff0c;基于混合专家架构&#xff0c;使用 Lean 4 框架进行形式化推理训练&#xff0c;参数规模达 6710 亿&#xff0c;结合强化学习与大规模合成数据…

如何用AI生成假期旅行照?

以下是2025年最新AI生成假期旅行照片的实用工具推荐及使用指南&#xff0c;结合工具特点、研发背景和适用场景进行综合解析&#xff1a; 一、主流AI旅行照片生成工具推荐与对比 1. 搜狐简单AI&#xff08;国内工具&#xff09; • 特点&#xff1a; • 一键优化与背景替换&…

ElaticSearch

ElaticSearch: 全文搜索 超级强&#xff0c;比如模糊查询、关键词高亮等 海量数据 高效查询&#xff0c;比传统关系数据库快得多&#xff08;尤其是搜索&#xff09; 灵活的数据结构&#xff08;Schema灵活&#xff0c;可以动态字段&#xff09; 分布式高可用&#xff0c;天…

Android开发,实现一个简约又好看的登录页

文章目录 1. 编写布局文件2.设计要点说明3. 效果图4. 关于作者其它项目视频教程介绍 1. 编写布局文件 编写activity.login.xml 布局文件 <?xml version"1.0" encoding"utf-8"?> <androidx.appcompat.widget.LinearLayoutCompat xmlns:android…

机器学习:【抛掷硬币的贝叶斯后验概率】

首先,抛硬币的问题通常涉及先验概率、似然函数和后验概率。假设用户可能想通过观察一系列的正面(H)和反面(T)来更新硬币的偏差概率。例如,先验可能假设硬币是均匀的,但随着观察到更多数据,用贝叶斯定理计算后验分布。 通常,硬币的偏差可以用Beta分布作为先验,因为它…

Echarts 问题:自定义的 legend 点击后消失,格式化 legend 的隐藏文本样式

文章目录 问题分析实现步骤代码解释问题 如下图所示,在自定义的 legend 点击后会消失 分析 我把隐藏的图例字体颜色设为灰色,可以借助 legend.formatter 和 legend.textStyle 结合 option.series 的 show 属性来达成。以下是具体的实现步骤和示例代码: <!DOCTYPE ht…

光谱相机如何提升目标检测与识别精度

光谱相机&#xff08;多光谱/高光谱&#xff09;通过捕捉目标在多个波段的光谱特征&#xff0c;能够揭示传统RGB相机无法感知的材质、化学成分及物理特性差异。以下是提升其目标检测与识别精度的核心方法&#xff1a; ‌1. 硬件优化&#xff1a;提升数据质量‌ ‌(1) 光谱分辨…

springboot项目配置nacos,指定使用环境

遇到这样一个问题&#xff0c;在开发、测试、生成环境之间切换的问题。 大多数的操作是通过修改spring.profiles.active来确定指向使用的环境配置文件&#xff0c;对应项目中需要增加对应的配置文件。 但是现在几乎所有公司都会有代码管理不管是SVN、git&#xff0c;这样就会涉…

AI代码审查的落地实施方案 - Java架构师面试实战

AI代码审查的落地实施方案 - Java架构师面试实战 本文通过模拟一位拥有十年Java研发经验的资深架构师马架构与面试官之间的对话&#xff0c;深入探讨了AI代码审查的落地实施方案。 第一轮提问 面试官&#xff1a; 马架构&#xff0c;请介绍一下您对AI代码审查的理解。 马架…

TDengine 订阅不到数据问题排查

简介 TDengine 在实际生产应用中&#xff0c;经常会遇到订阅程序订阅不到数据的问题&#xff0c;总结大部分都为使用不当或状态不正确等问题&#xff0c;需手工解决。 查看服务端状态 通过 sql 命令查看有问题的 topic 和consumer_group 组订阅是否正常。 select * from inf…

二、UI自动化测试02--元素定位方法

目录 一、定位⼀组元素⽅法二、XPath 定位⽅法1. 路径策略1.1 路径值获取⽅法 2. 利⽤元素属性策略利⽤元素属性策略的注意事项 3. 属性和逻辑结合4. 层级和属性结合策略5. XPath 延伸⽅法 三、CSS 定位⽅法1. CSS 策略: id选择器/class选择器/元素选择器/属性选择器2. 属性选择…

HotSpot的算法细节

可达性分析算法 以一系列“GC Roots”根对象作为起始节点集&#xff0c;从这些节点开始&#xff0c;根据引用关系向下搜索&#xff0c;搜索过程所走过的路径称为“引用链”&#xff08;Reference Chain&#xff09;&#xff0c;如果某个对象到GC Roots间没有任何引用链相连&am…