• 一个库帮你快速实现EF Core数据仓储模式


    前言

    EF Core是我们.NET日常开发中比较常用的ORM框架,今天大姚要分享的内容是如何使用EF Core Generic Repository通用仓储库来快速实现EF Core数据仓储模式。

    EF Core Generic Repository介绍

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

    值得推荐的.NET ORM框架

    对于还不知道怎么选择.NET ORM框架的同学可以看下面这两篇文章,希望对你会有所帮助😁。

    数据仓储(Repository)介绍

    Repository(仓储)是DDD(领域驱动设计)中的经典思想,可以归纳为介于实际业务层(领域层)和数据访问层之间的层,能让领域层能在感觉不到数据访问层的情况下,完成与数据库的交互和以往的DAO(数据访问)层相比,Repository层的设计理念更偏向于面向对象,而淡化直接对数据表进行的CRUD操作。

    类库特点

    • 该库可以在任何. NET Core或.NET应用程序上运行,该应用程序具有.NET Core 3.1、.NET Standard 2.1和.NET 5.0+支持。
    • 提供了带有数据库事务支持的通用存储库。
    • 拥有所有必需的方法,以任何你想要的方式查询数据,而无需从存储库获取IQueryable。
    • 支持Specification模式,使你能够动态构建查询,即延迟查询构建。
    • 具有针对你的查询的数据库级投影支持。
    • 支持针对你的关系型数据库运行原始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 options) : base(options)
            {
            }

            public DbSet UserInfo { get; set; }
        }

    新建UserInfoService(包含常见CRUD)

          public class UserInfoService
        {
            private readonly IRepository _repository;

            public UserInfoService(IRepository 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();
                foreach (var user in users)
                {
                    Console.WriteLine($"Id: {user.Id}, Name: {user.Name}, Age: {user.Age}, Email: {user.Email}");
                }

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

                // 根据条件查询用户
                var filteredUsers = await _repository.GetListAsync(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();

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

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

                IServiceProvider serviceProvider = services.BuildServiceProvider();

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

    项目源码地址

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

    优秀项目和框架精选

    该项目已收录到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技术社区微信交流群👪

  • 相关阅读:
    Django模板层
    【学习笔记】Public NOIP Round #3 简要题解
    推荐一款基于业务行为驱动开发(BDD)测试框架:Cucumber!
    5GNR——RACH随机接入流程(1):随机接入的原因
    喜报 | 思码逸 DevInsight 通过DaoCloud兼容性互认证
    教你自己搭建一个IP池(绝对超好用!!!!)
    文本相似度算法对比分析,短文本相似度主流算法
    Python中关于进度条的6个实用技巧
    理解DDD设计
    如何运用3DGIS技术整合智慧社区综合管理解决方案
  • 原文地址:https://www.cnblogs.com/Can-daydayup/p/18120034