马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
.NET Core ORM框架用法简述
一、主流.NET Core ORM框架概述
在.NET Core生态系统中,主流的ORM(Object-Relational Mapping)框架包括:
- Entity Framework Core (EF Core) - 微软官方推出的ORM框架
- Dapper - 轻量级微ORM
- Npgsql.EntityFrameworkCore.PostgreSQL - PostgreSQL专用EF Core提供程序
- Pomelo.EntityFrameworkCore.MySql - MySQL专用EF Core提供程序
- LINQ to DB - 高性能ORM
本文重点先容最常用的EF Core和Dapper。
二、Entity Framework Core (EF Core) 使用指南
1. 安装与配置
安装NuGet包:
- [/code] [code]dotnet add package Microsoft.EntityFrameworkCore
- dotnet add package Microsoft.EntityFrameworkCore.SqlServer # SQL Server提供程序
- # 或其他数据库提供程序
复制代码 DbContext配置:
- [/code] [code]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;");
- }
- }
复制代码 依赖注入配置(保举):
- [/code] [code]// Startup.cs或Program.cs
- builder.Services.AddDbContext<AppDbContext>(options =>
- options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
复制代码 2. 数据模子界说
实体类:
- [/code] [code]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配置:
- [/code] [code]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操纵
添加数据:
- [/code] [code]using (var context = new AppDbContext())
- {
- var user = new User { Name = "张三", BirthDate = new DateTime(1990, 1, 1) };
- context.Users.Add(user);
- context.SaveChanges();
- }
复制代码 查询数据:
- [/code] [code]// 简单查询
- 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();
复制代码 更新数据:
- [/code] [code]using (var context = new AppDbContext())
- {
- var user = context.Users.Find(1);
- if (user != null)
- {
- user.Name = "李四";
- context.SaveChanges();
- }
- }
复制代码 删除数据:
- [/code] [code]using (var context = new AppDbContext())
- {
- var user = context.Users.Find(1);
- if (user != null)
- {
- context.Users.Remove(user);
- context.SaveChanges();
- }
- }
复制代码 4. 高级功能
异步操纵:
- [/code] [code]var user = await context.Users.FindAsync(1);
- var users = await context.Users.Where(u => u.Name.Contains("张")).ToListAsync();
复制代码 事件处理:
- [/code] [code]using (var transaction = await context.Database.BeginTransactionAsync())
- {
- try
- {
- // 执行多个操作
- await context.SaveChangesAsync();
- await transaction.CommitAsync();
- }
- catch
- {
- await transaction.RollbackAsync();
- throw;
- }
- }
复制代码 迁移管理:
- [/code] [code]# 添加迁移
- dotnet ef migrations add InitialCreate
- # 更新数据库
- dotnet ef database update
- # 回滚迁移
- dotnet ef database update PreviousMigration
复制代码 三、Dapper使用指南
1. 安装与配置
安装NuGet包:
- [/code] [code]dotnet add package Dapper
- dotnet add package System.Data.SqlClient # SQL Server提供程序
复制代码 基本使用:
- [/code] [code]using var connection = new SqlConnection("Server=.;Database=MyApp;Trusted_Connection=True;");
- connection.Open();
复制代码 2. CRUD操纵
查询数据:
- [/code] [code]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 });
复制代码 插入数据:
- [/code] [code]var id = connection.QuerySingle<int>(
- "INSERT INTO Users (Name, BirthDate) VALUES (@Name, @BirthDate); SELECT SCOPE_IDENTITY();",
- new { Name = "张三", BirthDate = DateTime.Now });
复制代码 更新数据:
- [/code] [code]var affectedRows = connection.Execute(
- "UPDATE Users SET Name = @Name WHERE Id = @Id",
- new { Name = "李四", Id = 1 });
复制代码 删除数据:
- [/code] [code]var deletedRows = connection.Execute("DELETE FROM Users WHERE Id = @Id", new { Id = 1 });
复制代码 3. 高级功能
存储过程调用:
- [/code] [code]var users = connection.Query<User>("dbo.GetUsersByAgeRange",
- new { MinAge = 18, MaxAge = 30 },
- commandType: CommandType.StoredProcedure);
复制代码 多结果集处理:
- [/code] [code]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();
- }
复制代码 动态参数:
- [/code] [code]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异步支持原生支持需手动实现事件管理内置支持需手动实现缓存一级缓存无内置缓存 五、选择建议
- 选择EF Core当:
- 必要快速开发CRUD应用
- 团队熟悉ORM概念
- 必要数据库迁移功能
- 项目必要频仍变动数据模子
- 选择Dapper当:
- 必要极致性能
- 实行复杂SQL查询
- 已有成熟的SQL知识
- 项目以读为主,写操纵较少
六、最佳实践
EF Core最佳实践
- 合理使用耽误加载:
- [/code] [code]// 禁用延迟加载(推荐)
- protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
- {
- optionsBuilder.UseLazyLoadingProxies(false);
- }
复制代码 - 批量操纵优化:
- // 使用AddRange代替多个Add
- context.Users.AddRange(usersList);
- // 对于大量数据,考虑分批处理
- foreach (var batch in usersList.Batch(500))
- {
- context.Users.AddRange(batch);
- context.SaveChanges();
- }
复制代码 - 克制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最佳实践
- 使用参数化查询:
- [/code] [code]// 安全的方式
- connection.Query<User>("SELECT * FROM Users WHERE Name = @Name", new { Name = userInput });
- // 避免拼接SQL字符串(有SQL注入风险)
- // connection.Query<User>($"SELECT * FROM Users WHERE Name = '{userInput}'");
复制代码 - 连接受理:
- [/code] [code]// 使用using确保连接释放
- using (var connection = new SqlConnection(connectionString))
- {
- connection.Open();
- // 执行操作
- }
复制代码 - 存储过程调用:
- [/code] [code]var result = connection.QueryFirstOrDefault<int>(
- "dbo.GetUserCountByRole",
- new { RoleId = roleId },
- commandType: CommandType.StoredProcedure);
复制代码 七、性能优化技巧
EF Core性能优化
- 启用查询缓存:
- services.AddDbContext<AppDbContext>(options =>
- options.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking)
- .UseSqlServer(connectionString));
复制代码 - 使用AsNoTracking:
- // 只读场景使用
- var users = context.Users.AsNoTracking().ToList();
复制代码 - 投影查询:
- // 只查询需要的字段
- var userDtos = context.Users
- .Select(u => new UserDto { Id = u.Id, Name = u.Name })
- .ToList();
复制代码 Dapper性能优化
- 使用ExecuteScalar代替QueryFirstOrDefault:
- // 获取单个值
- var count = connection.ExecuteScalar<int>("SELECT COUNT(*) FROM Users");
复制代码 - 使用动态范例:
- // 当不需要强类型时
- var result = connection.Query("SELECT * FROM Users").FirstOrDefault();
复制代码 - 连接池配置:
- // 在连接字符串中配置
- "Server=.;Database=MyApp;User Id=user;Password=pass;Max Pool Size=100;"
复制代码 八、常见问题解决
EF Core常见问题
- N+1查询问题:
- 使用Include或ThenInclude预加载
- 使用Select投影查询
- 性能降落:
- 检查天生的SQL(使用日志
)
- 思量禁用变动跟踪(AsNoTracking)
- 优化数据库索引
- 迁移辩论:
- 使用dotnet ef migrations remove回滚
- 手动合并迁移文件
Dapper常见问题
- SQL注入风险:
- 连接泄漏:
- 确保使用using语句
- 实现IDisposable模式管理连接
- 结果映射错误:
- 检查列名与属性名匹配
- 使用Query<T>时确保T有默认构造函数
九、工具与扩展
EF Core工具
- EF Core Power Tools:
- 可视化查看数据库模子
- 快速天生实体类
- 实行数据库比较
- Entity Framework Core Profiler:
- 分析EF Core天生的SQL
- 性能监控

Dapper扩展
- Dapper.Contrib:
- connection.Insert(user);
- connection.Update(user);
复制代码
- Dapper.FluentMap:
- FluentMapper.Initialize(config =>
- {
- config.AddMap(new UserMap());
- });
复制代码
- DapperQueryBuilder:
- 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>();
复制代码
十、总结与建议
- EF Core适合:
- 快速开发的企业应用
- 必要数据库迁移的项目
- 团队熟悉ORM的情况
- Dapper适合:
- 高性能要求的微服务
- 复杂SQL查询场景
- 已有成熟SQL知识的项目
- 混合使用策略:
- 主框架使用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 Core
- return _context.Users.Find(id);
- }
-
- public IEnumerable<User> GetActiveUsers()
- {
- // 使用Dapper执行复杂查询
- return _dapperConnection.Query<User>("SELECT * FROM Users WHERE IsActive = 1");
- }
- }
复制代码
通过合理选择ORM框架并遵照最佳实践,可以显著进步.NET Core应用程序的开发效率和性能表现。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
|