Wpf 使用 Prism 实战开发Day11

news2024/12/28 20:29:03

仓储(Repository)/工作单元(Unit Of Work)模式

  •  仓储(rep):仓储接口定义了对实体类访问数据库及操作的方法。它统一管理数据访问的逻辑,并与业务逻辑层进行解耦。 简单的理解就是对访问数据库的一层接口封装。
  • 工作单元(uow):用来保证我们处理业务逻辑的,稳定性,完整性。防止在业务操作过程中,涉及对数据库多张表进行了增删改查(CURD)的时候,部分成功,部分失败。类似数据库中开的事务。

一.实现基础的仓储接口

1.新建一个 Repository (仓储) 文件夹,用来存放我们定义各个实体类对数据库操作的仓储。也就是对各个实体(表)进行增删改查的定义及实现,以及更高级的操作,例,分页,工作单元,事务,等等。

     1. 创建  待办事项仓储接口类 IToDoRepository  并且定义了(ToDo)实体对数据库CURD 的方法 

    public interface IToDoRepository
    {
        Task<bool> Add(ToDo toDo);
        bool Delete(ToDo toDo);
        bool Update(ToDo toDo);
        Task<ToDo> GetToDo();
    }

      2. 创建待办事项仓储的 实现类 ToDoRepository。该类继承自 IToDoRepository 仓储接口,并且需要实现父类所有定义的方法。

public class ToDoRepository : IToDoRepository
{
    private readonly MyToDoContext doContext;

    public ToDoRepository(MyToDoContext doContext)
    {
        this.doContext = doContext;
    }
    /// <summary>
    /// 增加
    /// </summary>
    /// <param name="toDo"></param>
    /// <returns></returns>
    public async Task<bool> Add(ToDo toDo)
    {
         await doContext.ToDo.AddAsync(toDo);
        return await doContext.SaveChangesAsync()>0;
    }

    /// <summary>
    /// 删除
    /// </summary>
    /// <param name="toDo"></param>
    /// <returns></returns>
    public  bool Delete(ToDo toDo)
    {
        doContext.ToDo.Remove(toDo);    
        return  doContext.SaveChanges()>0;
    }

    /// <summary>
    ///  更新
    /// </summary>
    /// <param name="toDo"></param>
    /// <returns></returns>
    public bool Update(ToDo toDo)
    {
        doContext.ToDo.Update(new ToDo
        {
            Id = toDo.Id,
            Title=toDo.Title,
            Content=toDo.Content,
        });
        return  doContext.SaveChanges()>0;
    }
    /// <summary>
    /// 查询
    /// </summary>
    /// <returns></returns>
    public async Task<ToDo> GetToDo()
    {
       var toDo=await doContext.ToDo.FirstOrDefaultAsync();
        return toDo;
    }
}
  1.  以上就是定义和实现的某个实体类仓储的基础写法。并且接口命名规范要用大写字母 I开头,实现类就去掉 I 字母。例如:定义仓储接口类: IToDoRepository, 仓储接口实现类:ToDoRepository
  2. 执行完操作后,要保存到数据库,需要调用 SaveChangesAsync。异步方法需要加Async,同步方法则去掉Async.其他的方法使用异步或同步也是同样的道理。

 二.如何使用仓储

    1. 在 Program.cs 中,进行注入

builder.Services.AddScoped<IToDoRepository,ToDoRepository>();

     2. 在控制器构造函数中实例化定义的仓储接口,并且通过 toDoRepository 实例去调用到定义的方法。

namespace MyToDo.Api.Controllers
{
    [ApiController]
    [Route("[controller]/[action]")]
    public class WeatherForecastController : ControllerBase
    {
        private readonly IToDoRepository toDoRepository;

        public WeatherForecastController(IToDoRepository toDoRepository)
        {
            this.toDoRepository = toDoRepository;
        }

        [HttpGet(Name = "GetToDo")]
        public async Task<ToDo> Get()
        {
           var  retsult= await toDoRepository.GetToDo();
            return retsult;
        }
        [HttpPost(Name = "Add")]
        public async Task<bool> AddAsync(ToDo toDo)
        {
            var retsult = await toDoRepository.Add(toDo);
            return retsult;
        }
        [HttpDelete(Name = "Delete")]
        public bool Deletes(ToDo toDo)
        {
            var retsult =  toDoRepository.Delete(toDo);
            return retsult;
        }
        [HttpPost(Name = "Update")]
        public bool UpdateAsync(ToDo toDo)
        {
            var retsult = toDoRepository.Update(toDo);
            return retsult;
        }
    }
}

  1. 测试接口的时候,点击Try in out,再执行 Execute.如果没有问题,就能看到查询返回的数据了。
  2. 注意:控制器里面的添加的路由,已经改成完整的路由了。由控制器/方法组合而成的唯一路由。例如:  [Route("[controller]/[action]")]
  3. 以上实现了 ToDo 实体对数据库基础的增删改查,虽然实际应用中还远远达不到使用需求,这个只是为了能去理解仓储模式的建立和使用。所有仓储底层操作数据库都大同小异。如果有别人写好的仓储,各性能各方面都相当ok,或者有其他的更主流的 orm框架,我们拿来用即可。避免重复造轮子,除非能造出更好的轮子了。


三.工作单元 (Unit Of Work)

  • 自个实现的仓储太简单,在实际应用中,如果涉及多张表操作,暂时无法保证数据的一致性。可能还需要花很多时间去修改代码达到使用需求。所以在 github 中已经有更好的实现方案 UnitOfWork,也包含了仓储接口的定义,直接拿来用即可。
  • 使用 uow 好处,多个仓储之间可以共享上下文(DbContext)以及保证操作数据一致性和完整性。

 1.  下载 Unit Of Work 源码

 2.在MyToDo.Api 项目中,创建一个 UnitOfWork 文件夹,并且把以下代码复制过来

 3. 创建一个类库项目去存放,共用的代码

4.选择 类库项目,点下一步,并且项目名称定义成 :MyToDo.Shared

5.把共用的代码,复制到 MyToDo.Shared 里面去

6.在MyToDo.Api 项目中,右键=》添加=》项目引用

7.勾选 MyToDo.Shared。表示在 MyToDo.Api引用该项目,点击确定。

8.最后,还需要在MyToDo.Api 项目的NuGet 中下载安装这个包

Microsoft.EntityFrameworkCore.AutoHistory 

  • 复制过来的代码,命名空间要更改。如果有其他报错,例如:报某个方法访问性不一至,找到那个方法。把访问修饰符 internal 改成public 就可以了。
  •  UnitOfWork 文件夹的源码以及 MyToDo.Shared 等2个公共文件夹里面的源码,自行去github下载了

  • 目前,整个完整的项目结构,如下:


四.如何使用工作单元 (Unit Of Work)

1. 先添加不同仓储的实现,例如,待办事项仓储 (ToDoRepository) 

    public class ToDoRepository : Repository<ToDo>, IRepository<ToDo>
    {
        public ToDoRepository(MyToDoContext dbContext) : base(dbContext)
        {

        }
    }

这个就是使用别人提供的 Unit Of Work中已写好的仓储接口,然后自己自定义仓储去继承并实现它的一个标准写法。这样就能调用到别人集成好的方法。集成到自己的业务逻辑中去。


2.在Program.cs 中进行依赖注入

builder.Services.AddDbContext<MyToDoContext>(option =>
{
    //获取数据库连接
    var connectionString = builder.Configuration.GetConnectionString("ToDoConnection");
    //使用sqlite
    option.UseSqlite(connectionString);
}).AddUnitOfWork<MyToDoContext>() //注入工作单元
.AddCustomRepository<ToDo,ToDoRepository>() //注入仓储
.AddCustomRepository<Memo, MemoRepository>()
.AddCustomRepository<User, UserRepository>();


 3.使用方式

namespace MyToDo.Api.Controllers
{
    [ApiController]
    [Route("[controller]/[action]")]
    public class WeatherForecastController : ControllerBase
    {
        private readonly IUnitOfWork unitOfWork;

        public WeatherForecastController(IUnitOfWork unitOfWork)
        {
            this.unitOfWork = unitOfWork;
        }

        [HttpGet(Name = "GetToDo")]
        public async Task<List<ToDo>> Get()
        {
            var  service= unitOfWork.GetRepository<ToDo>();//获取仓储服务
            return (List<ToDo>)await service.GetAllAsync();
            
        }
    }
}

4.最后效果

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

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

相关文章

百家大吉·夕阳关爱——昌岗街微型养老博览会

居民热情参与博览会 为让长者了解及选择适合自己的养老服务&#xff0c;昌岗街在2023年12月27日开展以“百家大吉夕阳关爱”为主题的昌岗街微型养老服务公益博览会活动&#xff0c;通过搭建养老服务机构供需服务平台&#xff0c;拓宽社区长者了解正规养老服务机构的渠道&#…

视频转码:掌握mp4视频格式转FLV视频的技巧,视频批量剪辑方法

在多媒体时代&#xff0c;视频格式的转换成为一种常见的需求。把MP4格式转换为FLV格式&#xff0c;FLV格式的视频文件通常具有较小的文件大小&#xff0c;同时保持了较好的视频质量。批量剪辑视频的方法能大大提高工作效率。下面来看云炫AI智剪如何进行MP4到FLV的转码&#xff…

写在学习webkit过程的前面

webkit起源于KHTML&#xff0c;是KDE开源项目的KHTML和KJS引擎的一部分。在它的诞生和发展过程中&#xff0c;由两家著名的公司参与开发过程中&#xff0c;造成两次裂变。诞生两个内核webkit和blink&#xff0c;并发展和产生了两个主流的浏览器&#xff0c;分别为safari和chrom…

Unity网络通讯学习

---部分截图来自 siki学院Unity网络通讯课程 Socket 网络上的两个程序通过一个双向的通信连接实现数据交换&#xff0c;这个连接的一端称为一个 Socket &#xff0c;Socket 包含了网络通信必须的五种信息 Socket 例子{ 协议&#xff1a; TCP 本地&#xff1a; IP &#xff…

【Linux Shell】9. 流程控制

文章目录 【 1. if else 判断 】1.1 if1.2 if else1.3 if elif else1.4 实例 【 2. case 匹配 】【 3. 循环 】3.1 for 循环3.2 while 循环3.3 until 循环3.4 无限循环3.5 跳出循环3.5.1 break 跳出所有循环3.5.2 continue 仅跳出当前循环 【 1. if else 判断 】 1.1 if fi 是…

【双指针】001移动零_C++

题目链接&#xff1a;移动零 目录 题目解析 代码书写 知识补充 题目解析 题目让我们求必须在不复制数组的情况下,编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 这题我们可以用双指针的方法来写&#xff1a; 我们这里将用两个数组下标来…

Linux tail命令详解和高级用法举例

目 录 一、概述 二、tail命令解释 1&#xff0e;命令格式; 2&#xff0e;功能 3&#xff0e;选项 4&#xff0e;选项的基本用法 &#xff08;1&#xff09; 显示行号 &#xff08;2&#xff09;忽略指定字符数 &#xff08;3&#xff09; 不显示文件名 三…

GVM垃圾收集算法

分代收集理论 目前主流JVM虚拟机中的垃圾收集器&#xff0c;都遵循分代收集理论&#xff1a; 弱分代&#xff1a;绝大多数对象都是朝生夕灭强分带&#xff1a;经历越多次垃圾收集过程的对象&#xff0c;越难以回收&#xff0c;难以消亡 按照分代收集理论设计的“分代垃圾收集…

鸿蒙原生应用再添新丁!天眼查 入局鸿蒙

鸿蒙原生应用再添新丁&#xff01;天眼查 入局鸿蒙 来自 HarmonyOS 微博1月12日消息&#xff0c;#天眼查启动鸿蒙原生应用开发#作为累计用户数超6亿的头部商业信息查询平台&#xff0c;天眼查可以为商家企业&#xff0c;职场人士以及普通消费者等用户便捷和安全地提供查询海量…

迅为RK3588开发板编译 Buildroot单独编译图形化界面三

第三步&#xff1a;编译 Recovery 首先在 linux 源码目录下输入以下命令进入编译的 UI 界面&#xff0c;进入之后如下所示&#xff1a; ./build.sh 然后将光标移动到第四个 recovery&#xff0c;点击回车即可开始 recovery 的编译&#xff0c;编译过程如下所示&#xff1a; 编…

python爬虫实战(6)--获取某度热榜

1. 项目描述 需要用到的类库 pip install requests pip install beautifulsoup4 pip install pandas pip install openpyxl然后&#xff0c;我们来编写python脚本&#xff0c;并引入需要的库&#xff1a; import requests from bs4 import BeautifulSoup import pandas as p…

C++多线程学习[二]:线程的传参以及传参的一些坑

一、线程的传参 #include<iostream> #include<thread> #include<string> using namespace std; void threadtest(int a,double b,string str) {this_thread::sleep_for(100ms);cout << a << " " << b << " " &…

【K8s学习】

k8s的简单执行流程&#xff1a; Kubernetes Master&#xff08;API Server、Scheduler等组件&#xff09;负责调度Pod到合适的Node上。 当Pod被调度到某个Node时&#xff0c;该Node上的kubelet代理会收到指令并开始执行Pod的生命周期管理任务&#xff0c;包括创建、监控和终止P…

基于stm32f4的蓝牙控制小车

1. 引言 蓝牙的创始人是瑞典爱立信公司&#xff0c;蓝牙技术是一种无限数据与语音通信的开放性全球规范&#xff0c;它以低成本的近距离无线连接为基础&#xff0c;为固定与移动设备通信环境建立一个特别连接。手机之间通过蓝牙实现数据共享成为常理&#xff0c;将手机变为遥…

500mA High Voltage Linear Charger with OVP/OCP

一、General Description YHM2810 is a highly integrated, single-cell Li-ion battery charger with system power path management for space-limited portable applications. The full charger function features Trickle-charge, constant current fast charge and const…

php 的数学常用函数

目录 1.常用列表 2.代码示例 1.常用列表 函数名描述输入输出abs()求绝对值数字绝对值数字ceil()进一法取整浮点数进一取整floor()舍去法求整浮点数直接舍去小数部分fmod()浮点数取余 两个浮点 数,x>y 浮点余数 pow()返回数的n次方基础数n次方乘方值round()浮点数四舍五入…

HTTP 常见协议:选择正确的协议,提升用户体验(上)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

数据库创建表并插入数据练习题

一、创建表的要求 创建一个英雄表(hero) 主键 name nickname address groups email telphone 二、 操作步骤 1.登录MySQL [rootlocalhost ~]# systemctl start mysqld [rootlocalhost ~]# mysql -uroot -p Enter password: Welcome to the MySQL monitor. Commands end with…

共商、共建、共谋未来,国台与经销商的“双向奔赴”

执笔 | 洪大大 编辑 | 扬 灵 1月9日&#xff0c;以“共商共建同奋进 共创共享新名酒”为主题的国台2024年全国经销商大会在广州召开。大会彰显了国台对经销商的尊重&#xff0c;将经销商放在C位&#xff0c;进一步强化厂商同心的经营理念。 此次大会不仅是对国台2023年市场…

1、理解Transformer:革新自然语言处理的模型

目录 一、论文题目 二、背景与动机 三、卖点与创新 四、解决的问题 五、具体实现细节 0. Transformer 架构的主要组件 1. 注意力、自注意力&#xff08;Self-Attention&#xff09;到多头注意力&#xff08;Multi-Head Attention&#xff09; 注意力到底是做什么的&…