Wpf 使用 Prism 实战开发Day11

仓储(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");//使用sqliteoption.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.hqwc.cn/news/343544.html

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

相关文章

Tensorflow2.0笔记 - 修改形状和维度

本次笔记主要使用reshape&#xff0c;transpose&#xff0c;expand_dim&#xff0c;和squeeze对tensor的形状和维度进行操作。 import tensorflow as tf import numpy as nptf.__version__#tensor的shape和维数获取 #假设下面这个tensor表示4张28*28*3的图片 tensor tf.rando…

开发代码基础

首先安装驱动&#xff0c;在ARDUINO环境下安装&#xff0c;然后安装开发板&#xff0c;详见哔哩哔哩教程 1&#xff1a;接入点模式&#xff08;也称 AP&#xff09; 通过以下示例程序&#xff0c;NodeMCU将会建立一个名为taichi-maker的WiFI。您可以使用手机或电脑连接该WiFi…

Spark的内核调度

目录 概述 RDD的依赖 DAG和Stage DAG执行流程图形成和Stage划分 Stage内部流程 Spark Shuffle Spark中shuffle的发展历程 优化前的Hash shuffle 经过优化后的Hash shuffle Sort shuffle Sort shuffle的普通机制 Job调度流程 Spark RDD并行度 概述 Spark内核调度任务: 1…

U盘启动安装win11遇到缺少计算机所需的介质驱动程序问题

一、使用U盘制作启动盘遇到问题 下载了windows原版镜像&#xff0c;验证了md5&#xff0c;确保文件没有损坏。使用ultroiso制作u盘启动盘&#xff0c;开始安装后出现下图的报错&#xff1a; 在网上搜索解决方案&#xff0c;主要有以下几种&#xff1a; 安装的时候&#xff0c…

Java Swing 图书借阅系统 窗体项目 期末课程设计 窗体设计

视频教程&#xff1a; 【课程设计】图书借阅系统 功能描述&#xff1a; 图书管理系统有三个角色&#xff0c;系统管理员、图书管理员、借阅者&#xff1b; 系统管理员可以添加借阅用户&#xff1b; ​图书管理员可以添加图书&#xff0c;操作图书借阅和归还&#xff1b; 借…

最大公共子串

解题思路&#xff1a; 解题代码&#xff1a; UP主运用的方法很巧妙。厉害。

GitLab 502 Whoops, GitLab is taking too much time to respond. 解决

1、先通过gitlab-ctl restart进行重启&#xff0c;2分钟后看是否可以正常访问&#xff0c;为什么要2分钟&#xff0c;因为gitlab启动会有很多配套的服务启动&#xff0c;包括postgresql等 2、如果上面不行&#xff0c;再看gitlab日志&#xff0c;通过gitlab-ctl tail命令查看&…

服务端性能测试——性能测试工具JMeter-L1

第一遍没学懂&#xff0c;后续文章会更新~ 目录&#xff1a; 1.JMeter介绍与安装Meter简介JMeter安装2.JMeter的运行JMeter运行、界面功能简介3.使用代理服务器录制请求录制压测脚本&#xff08;一&#xff09;Web端脚本录制方法4.测试计划5.线程组6.控制器7.JMeter采样器/取…

软件测试之项目立项与需求评审

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;软件测试面试题分享&#xff1a; 1000道软件测试面试题及答案&#x1f4e2;软件测试实战项目分享&#xff1a; 纯接口项目-完…

【AI视野·今日NLP 自然语言处理论文速览 第七十二期】Mon, 8 Jan 2024

AI视野今日CS.NLP 自然语言处理论文速览 Mon, 8 Jan 2024 Totally 17 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computation and Language Papers DeepSeek LLM: Scaling Open-Source Language Models with Longtermism Authors DeepSeek AI Xiao Bi, Deli Ch…

代码随想录二刷 |二叉树 | 二叉搜索树中的众数

代码随想录二刷 &#xff5c;二叉树 &#xff5c; 二叉搜索树中的众数 题目描述解题思路递归法非二叉搜索树的方式二叉搜索树的方式 迭代法 题目描述 501.二叉搜索树中的众数 给定一个有相同值的二叉搜索树&#xff08;BST&#xff09;&#xff0c;找出 BST 中的所有众数&…

第三节课 基于 InternLM 和 LangChain 搭建你的知识库作业

文章目录 笔记作业 笔记 基于书生浦语大模型应用开发范式介绍&#xff1a;https://blog.csdn.net/m0_49289284/article/details/135467197基于InternLM 和 LangChain 搭建你的知识库&#xff1a;Demohttps://blog.csdn.net/m0_49289284/article/details/135482658 作业 基础…