使用EF Core Generic Repository通用仓储库快速实现数据访问(ORM)

EF Core是.NET开发中常用的ORM框架。今天我们将分享如何利用EF Core Generic Repository通用仓储库来快速实现EF Core数据仓储模式。

EF Core Generic Repository介绍

EF Core Generic Repository是针对EF Core ORM的通用仓储库实现。它的目标是简化开发人员为每个.NET Core和.NET项目编写仓储层的工作。通过使用这个库,开发人员可以更轻松地管理数据访问层,提高开发效率。

值得推荐的.NET ORM框架

对于还不知道如何选择.NET ORM框架的同学,可以参考以下两篇文章,希望对你会有所帮助?。

  • 16个值得推荐的.NET ORM框架
  • .NET ORM框架使用情况统计

数据仓储(Repository)介绍

数据仓储(Repository)是DDD(领域驱动设计)中的经典思想。它可以归纳为介于实际业务层(领域层)和数据访问层之间的层级。数据仓储层的设计理念更偏向于面向对象,而淡化直接对数据表进行CRUD操作。

类库特点

  • 该库支持任何.NET Core或.NET应用程序,并且具有.NET Core 3.1、.NET Standard 2.1和.NET 5.0+支持。
  • 提供了带有数据库事务支持的通用存储库。
  • 拥有所有必需的方法,以任何你想要的方式查询数据,而无需从存储库获取IQueryable。
  • 支持Specification<T>模式,能够动态构建查询,即延迟查询构建。
  • 具有针对你的查询的数据库级投影支持。
  • 支持针对你的关系型数据库运行原始SQL命令。
  • 支持选择是否要跟踪你的查询实体/实体。
  • 支持在确实需要时重置你的EF Core DbContext状态。
  • 具有完整的单元测试支持。
  • 支持分页、原始SQL查询支持复杂类型和原始类型。

项目源代码

新建控制台应用

新建名为: GenericRepositoryExercise 的控制台应用。

相关类库安装

搜索名为: TanvirArjel.EFCore.GenericRepository 的NuGet安装。

因为我们要访问Microsoft SQL Server数据库,因此我们需要安装 Microsoft.EntityFrameworkCore.SqlServer NuGet包。

新建UserInfo类

[Table("UserInfo")]
public class UserInfo
{
[Key]
public int Id { get; set; }

[Required]
public string Name { get; set; }

[Required]
public int Age { get; set; }

[Required]
public string Email { get; set; }
}

新建数据库上下文类

新建名为: TestDbContext 数据库上下文类。

public class TestDbContext : DbContext
{
public TestDbContext(DbContextOptions<TestDbContext> options) : base(options)
{
}

public DbSet<UserInfo> UserInfo { get; set; }
}

新建UserInfoService(包含常见CRUD)

public class UserInfoService
{
private readonly IRepository<TestDbContext> _repository;

public UserInfoService(IRepository<TestDbContext> repository)
{
_repository = repository;
}

public async Task UserInfoCRUD()
{
// 创建一个新用户
var newUser = new UserInfo { Name = "daydayup", Age = 28, Email = "daydayup@example.com" };
await _repository.AddAsync(newUser);
await _repository.SaveChangesAsync();

// 更新用户信息
newUser.Email = "new_updated@example.com";
_repository.Update(newUser);
await _repository.SaveChangesAsync();

// 删除用户
_repository.Remove(newUser);
await _repository.SaveChangesAsync();

// 查询所有用户
var users = await _repository.GetListAsync<UserInfo>();
foreach (var user in users)
{
Console.WriteLine($"Id: {user.Id}, Name: {user.Name}, Age: {user.Age}, Email: {user.Email}");
}

//查询总数
var totalCount = await _repository.GetCountAsync<UserInfo>();

// 根据条件查询用户
var filteredUsers = await _repository.GetListAsync<UserInfo>(u => u.Age > 25);
foreach (var user in filteredUsers)
{
Console.WriteLine($"Id: {user.Id}, Name: {user.Name}, Age: {user.Age}, Email: {user.Email}");
}
}
}

在Program.cs中注册相关服务

internal class Program
{
static async Task Main(string[] args)
{
//设置依赖注入容器
IServiceCollection services = new ServiceCollection();
services.AddScoped<UserInfoService>();

var connectionString = "Server=.;Database=MyTestDB;User Id=test;Password=123456;trustServerCertificate=true;";
services.AddDbContext<TestDbContext>(option => option.UseSqlServer(connectionString));

//注册DbConext后立即调用它
services.AddGenericRepository<TestDbContext>();

IServiceProvider serviceProvider = services.BuildServiceProvider();

//从容器中获取UserInfoService实例并执行操作
var userInfoService = serviceProvider.GetRequiredService<UserInfoService>();
await userInfoService.UserInfoCRUD();
}
}

项目源码地址

更多项目实用功能和特性欢迎前往项目的开源地址查看,别忘了给项目一个Star支持?。

  • GitHub源码: https://github.com/TanvirArjel/EFCore.GenericRepository
  • 文章示例源码: https://github.com/YSGStudyHards/DotNetExercises/tree/master/GenericRepositoryExercise

优秀项目和框架精选

该项目已收录到C#/.NET/.NET Core优秀项目和框架精选中。关注优秀项目和框架精选能让你及时了解C#、.NET和.NET Core领域的最新动态和最佳实践,提高开发工作效率和质量。坑已挖,欢迎大家踊跃提交PR推荐或自荐(让优秀的项目和框架不被埋没?)。

https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md

DotNetGuide技术社区交流群

  • DotNetGuide技术社区是一个面向.NET开发者的开源技术社区,旨在为开发者们提供全面的C#/.NET/.NET Core相关学习资料、技术分享和咨询、项目框架推荐、求职和招聘资讯、以及解决问题的平台。
  • 在DotNetGuide技术社区中,开发者们可以分享自己的技术文章、项目经验、学习心得、遇到的疑难技术问题以及解决方案,并且还有机会结识志同道合的开发者。
  • 我们致力于构建一个积极向上、和谐友善的.NET技术交流平台。无论您是初学者还是有丰富经验的开发者,我们都希望能为您提供更多的价值和成长机会。

欢迎加入DotNetGuide技术社区微信交流群?

标签:游戏攻略