Wpf 使用 Prism 实战开发Day13

news2024/9/20 12:42:36

配置 AutoMapper 关系映射

在上一节 ToDoController 控制器,或 IToDoService 服务接口中,方法的传参都是直接传的实体类。但在实际开发过程中,这样是不允许的。标准且规范的做法是,定义一个数据传输层,即Dto层。


 一.在MyToDo.Api 项目中安装 Auto Mapper


二. 在MyToDo.Shared 项目中创建一个Dtos文件夹,存放Dto文件

1. 创建 BaseDto 基类,用于存放共用属性。

    public class BaseDto
    {
        public int Id { get; set; }
    }

2. 创建待办事项 Dto类,并继承自 BaseDto 基类 

    /// <summary>
    /// 待办事项数据实体
    /// </summary>
    public class ToDoDto:BaseDto
    {
        public string Title { get; set; }
        public string Content { get; set; }
        public int Status { get; set; }
    }

3.由于我们的客户端是Wpf 项目,各属性需要实现通知绑定 。所以 BaseDto类需要进行修改,并且要继承自 INotifyPropertyChanged 接口。同时还要实现一个通知绑定的方法。

    public class BaseDto:INotifyPropertyChanged
    {
        public int Id { get; set; }

        public event PropertyChangedEventHandler? PropertyChanged;

        /// <summary>
        /// CallerMemberName 是一个自动获取传入名称的属性
        /// </summary>
        /// <param name="propertyName"></param>
        public void OnPropertyChanged([CallerMemberName] string propertyName = "")
        {
            PropertyChanged?.Invoke(this,new PropertyChangedEventArgs(propertyName));
        }
    }

4.接着,要需要再修改 ToDoDto ,让它具备实现属性绑定通知功能。

  /// <summary>
  /// 待办事项数据实体
  /// </summary>
  public class ToDoDto:BaseDto
  {
      private string title;
      private string content;
      private int status;
      public string Title 
      {
          get { return title; }
          set {  title = value; OnPropertyChanged(); }
      }
      public string Content 
      {
          get { return content; }
          set { content = value; OnPropertyChanged(); }
      }
      public int Status 
      {
          get { return status; }
          set { status = value; OnPropertyChanged(); }
      }
  }

三.把实体类(ToDo)和定义的数据传输类(ToDoDto) 进行关系映射

1.在 MyToDo.Api 项目中,创建一个 Extensions 扩展文件夹。再创建一个 AutoMapperProFile 类,并且继承自 MapperConfigurationExpression,该类用于配置所有实体类和数据传输类的映射关系。

    public class AutoMapperProFile:MapperConfigurationExpression
    {
        public AutoMapperProFile()
        {
            /// 实体类和数据传输类进行映射
            CreateMap<ToDo, ToDoDto>().ReverseMap();
        }
    }
  • ReverseMap 表示两者之间可以互相进行转换。

四.修改 ToDoController 控制器传参和IToDoService 服务传参

1. IToDoService接口类传入的ToDo实体改成ToDoDto

    public interface IToDoService:IBaseService<ToDoDto>
    {

    }

2.ToDoService 服务实现类,所有传入参数是ToDo实体,需全部换成ToDoDto。并且需要在构造函数中注入 IMapper 接口。

 /// <summary>
 /// 待办事项的实现
 /// </summary>
 public class ToDoService : IToDoService
 {
     private readonly IUnitOfWork work;
     private readonly IMapper mapper;

     public ToDoService(IUnitOfWork work,IMapper mapper)
     {
         this.work = work;
         this.mapper = mapper;
     }
     public async Task<ApiResponse> AddAsync(ToDoDto model)
     {
         try
         {
             var doto= mapper.Map<ToDo>(model);//进行数据映射转换
             await work.GetRepository<ToDo>().InsertAsync(doto);
             if (await work.SaveChangesAsync() > 0) //保存成功
             {
                 return new ApiResponse(true, model); //返回true,并把添加的实体返回
             }
             return new ApiResponse("添加数据失败");
         }
         catch (Exception ex)
         {
             return new ApiResponse(ex.Message);
         }
     }

     public async Task<ApiResponse> DeleteAsync(int id)
     {
         try
         {
             var repository= work.GetRepository<ToDo>();//获取仓储
             //删除之前,先进行查询
             var todo = await repository.GetFirstOrDefaultAsync(predicate:x=>x.Id.Equals(id));
             repository.Delete(todo);
             if (await work.SaveChangesAsync() > 0) //删除成功
             {
                 return new ApiResponse(true, "删除成功"); 
             }
             return new ApiResponse("删除数据失败");
         }
         catch (Exception ex)
         {
             return new ApiResponse(ex.Message);
         }
     }

     public async Task<ApiResponse> GetAllAsync()
     {
         try
         {
            var todos= await work.GetRepository<ToDo>().GetAllAsync();
             return new ApiResponse(true, todos); //返回true,并返回所有数据
         }
         catch (Exception ex)
         {
             return new ApiResponse(ex.Message);
         }
     }

     public async Task<ApiResponse> GetSingleAsync(int id)
     {
         try
         {
            var todo= await work.GetRepository<ToDo>().GetFirstOrDefaultAsync(predicate: x => x.Id.Equals(id));
             return new ApiResponse(true, todo); //把找到的数据返回
         }
         catch (Exception ex)
         {
             return new ApiResponse(ex.Message);
         }
     }

     public async Task<ApiResponse> UpdateAsync(ToDoDto model)
     {
         try
         {
             var dbdoto = mapper.Map<ToDo>(model);
             var repository = work.GetRepository<ToDo>();//获取仓储
             //更新之前,先拿到要更新的数据
             var todo = await repository.GetFirstOrDefaultAsync(predicate: x => x.Id.Equals(dbdoto.Id));
             todo.Title = dbdoto.Title;
             todo.Content = dbdoto.Content;
             todo.Status = dbdoto.Status;
             todo.UpdateDate = DateTime.Now;
             repository.Update(todo);
             if (await work.SaveChangesAsync() > 0) //更新成功
             {
                 return new ApiResponse(true, "更新成功");
             }
             return new ApiResponse("更新数据失败");
         }
         catch (Exception ex)
         {
             return new ApiResponse(ex.Message);
         }
     }
 }
  •  IMapper 接口里的 Map 方法,用于 Dto和实体类之间的数据映射转换

3.把ToDoController 控制器传入的ToDo实体改成ToDoDto

 [ApiController]
 [Route("api/[controller]/[action]")]
 public class ToDoController:ControllerBase
 {
     private readonly IToDoService service;

     public ToDoController(IToDoService service)
     {
         this.service = service;
     }

     [HttpGet]
     public async Task<ApiResponse> Get(int id)=> await service.GetSingleAsync(id);

     [HttpGet]
     public async Task<ApiResponse> GetAll() => await service.GetAllAsync();

     [HttpPost]
     public async Task<ApiResponse> Add([FromBody]ToDoDto model) => await service.AddAsync(model);

     [HttpPost]
     public async Task<ApiResponse> Update([FromBody] ToDoDto model) => await service.UpdateAsync(model);

     [HttpDelete]
     public async Task<ApiResponse> Delete(int id) => await service.DeleteAsync(id);
 }

五.最后,需要在Program.cs 中,进行注册 AutoMapper 服务

//注入AutoMapper
builder.Services.AddSingleton(new MapperConfiguration(config =>
{
    config.AddProfile(new AutoMapperProFile());
}).CreateMapper());


六.运行测试接口都正常,证明配置AutoMapper 成功了

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

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

相关文章

荣誉艾尔迪亚人的题解

目录 原题描述&#xff1a; 题目背景 题目描述 输入格式 输出格式 样例 Input 1 Output 1 Input 2 Output 2 数据范围&#xff1a; 样例解释 主要思路&#xff1a; 代码code&#xff1a; 原题描述&#xff1a; 时间限制: 1000ms 空间限制: 65536kb 题目背景 ​…

GPT应用_PrivateGPT

项目地址&#xff1a;https://github.com/imartinez/privateGPT 1 功能 1.1 整体功能&#xff0c;想解决什么问题 搭建完整的 RAG 系统&#xff0c;与 FastGPT 相比&#xff0c;界面比较简单。但是底层支持比较丰富&#xff0c;可用于知识库的完全本地部署&#xff0c;包含大…

如何选择工程师职称申报的专业?

选择适合自己的职称评定专业&#xff0c;需从官方申报范围、公示名单中寻找答案&#xff0c;并选择适合自己的评审方式。需具备一定的工作年限、学历要求和充分证明自己能力水平的材料&#xff0c;方可获得职称资格。 在职称评定之路上&#xff0c;选择一个适合自己的专业&…

论文阅读笔记AI篇 —— Transformer模型理论+实战 (四)

论文阅读笔记AI篇 —— Transformer模型理论实战 &#xff08;四&#xff09; 一、理论1.1 理论研读1.2 什么是AI Agent? 二、实战2.1 先导知识2.1.1 tensor的创建与使用2.1.2 PyTorch的模块2.1.2.1 torch.nn.Module类的继承与使用2.1.2.2 torch.nn.Linear类 2.2 Transformer代…

设计模式--组合模式

缘起 某日&#xff0c;小明公司最近接到一个办公管理系统的项目&#xff0c;并且在每个城市都有分部。这属于是很常见的OA系统&#xff0c;只要前期将需求分析完善好&#xff0c;中后期开发维护是不难的。 然而&#xff0c;总部公司使用后觉得很OK&#xff0c;想要其他城市的…

【Proxy】Windows 10 的 Command Line Proxy 设置

【Proxy】Windows 10 的 Command Line Proxy 设置 1 本机环境2 PowerShell3 CMD 1 本机环境 Windows 10v2rayN 在 v2rayN 界面下方可以看到 socks 和 http 的端口号&#xff0c;分别为 10808 和 10809 2 PowerShell 每次打开新窗口&#xff0c;执行下面的命令 $env:HTTP_…

无刷电机行业调研:市场销售规模达到537亿元

无刷直流电机(BLDC&#xff1a;Brushless Direct Current Motor)&#xff0c;也被称为电子换向电机(ECM或EC电机)或同步直流电机&#xff0c;是一种使用直流电(DC)电源的同步电机。无刷直流电机实质上为采用直流电源输入&#xff0c;并用逆变器变为三相交流电源&#xff0c;带位…

GitHub图床TyporaPicGo相关配置

本文作者&#xff1a; slience_me 文章目录 GitHub图床&Typora&PicGo相关配置1. Github配置2. picGo配置3. Typora配置 GitHub图床&Typora&PicGo相关配置 关于Typora旧版的百度网盘下载路径 链接&#xff1a;https://pan.baidu.com/s/12mq-dMqWnRRoreGo4MTbKg?…

三国游戏(寒假每日一题+贪心、枚举)

题目 小蓝正在玩一款游戏。 游戏中魏蜀吴三个国家各自拥有一定数量的士兵 X,Y,Z&#xff08;一开始可以认为都为 0&#xff09;。 游戏有 n 个可能会发生的事件&#xff0c;每个事件之间相互独立且最多只会发生一次&#xff0c;当第 i个事件发生时会分别让 X,Y,Z 增加 Ai,Bi…

零基础学Python(2)— 安装Python开发工具之PyCharm

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。PyCharm是由JetBrains公司开发的一款Python开发工具。在Windows、Mac OS和Linux操作系统中都可以使用。它具有语法高亮显示、Project&#xff08;项目&#xff09;管理代码跳转、智能提示、自动完成、调试、单元测试和版本…

关于SQL-case when最全面的学习笔记

case when 推荐学习书籍&#xff1a;1、SQL基础教程 6-32、SQL进阶教程 1-1 case when 是SQL语法中提供的标准的条件分支。 条件分支在MYSQL中即为IF函数&#xff0c;不同的数据库都会提供自己的一些函数&#xff0c;但是CASE WHEN 更加通用。 CASE语句的两种写法 1、搜索CASE…

Ubuntu使用docker-compose安装mysql8或mysql5.7

ubuntu环境搭建专栏&#x1f517;点击跳转 Ubuntu系统环境搭建&#xff08;十四&#xff09;——使用docker-compose安装mysql8或mysql5.7 文章目录 Ubuntu系统环境搭建&#xff08;十四&#xff09;——使用docker-compose安装mysql8或mysql5.7MySQL81.新建文件夹2.创建docke…

在码云(gitee)里面提交代码进行保存步骤(自留笔记)

一些需要用到的软件需要自行下载 视频可观看https://www.bilibili.com/video/BV1hf4y1W7yT/ 步骤&#xff1a; 1.打开码云&#xff0c;点击加号&#xff0c;创建仓库 2.此处我的仓库选择私有&#xff0c;也可以选择开源&#xff0c;选择开源时&#xff0c;注意把弹出来的选项全…

「Kafka」Broker篇

「Kafka」Broker篇 主要讲解的是在 Kafka 中是怎么存储数据的&#xff0c;以及 Kafka 和 Zookeeper 之间如何进行数据沟通的。 Kafka Broker 总体工作流程 Zookeeper 存储的 Kafka 信息 启动 Zookeeper 客户端&#xff1a; [atguiguhadoop102 zookeeper-3.5.7]$ bin/zkCli.sh通…

【JavaEE】_网络编程基础

目录 1. 网络编程基础 1.1 网络编程定义 1.2 网络编程中的基本概念 1.2.1 API 1.2.2.发送端和接收端 1.2.3 请求和响应 1.2.4 客户端和服务端 2. Socket 套接字 2.1 概念 2.2 分类 3. UDP数据报套接字编程 3.1 DatagramSocket API 3.1.1 含义 3.1.2 构造方法 3…

全景摄像机行业分析:市场规模不可限量

早期的全景相机行业竞争格局较为多元。近年来随着行业技术不断成熟&#xff0c;市场的竞争格局由多家参与逐步向头部企业聚拢&#xff0c;国内企业凭借图像处理技术优势在全景相机行业中逐步抢占市场份额。 全景摄像机&#xff0c;是可以独立实现大范围无死角监控的摄像机。 一…

OpenVINS学习7——评估工具的简单使用

前言 OpenVINS自带评估工具&#xff0c;这里记录一下使用方法&#xff0c;我是以VIRAL数据集为例&#xff0c;但是目前仍然有问题&#xff0c;发现误差很大&#xff0c;我还没搞明白哪里出了问题。 工具介绍 主要参考 https://docs.openvins.com/eval-error.html https://bl…

ELK 日志分析系统

目录 一、日志管理方案 二、完整日志系统基本特征 三、ELK 简介 ELK组件&#xff1a; 1、ElasticSearch 2、Logstash 3、Kibana 可以添加的其它组件&#xff1a; 1、Filebeat 2、缓存/消息队列&#xff08;redis、kafka、RabbitMQ等&#xff09; 3、Fluentd 三、ELK …

作业-数组计数法

目录 数字出现次数 题目描述 输入 输出 输入复制 输出复制 求n个数中每个数出现的次数 题目描述 输入 输出 输入复制 输出复制 声音识别 题目描述 输入 输出 输入复制 输出复制 选班委 题目描述 输入 输出 输入复制 输出复制 数字出现次数 题目描述 …

解析智能酒精壁炉不完全燃烧的成因及潜在问题

解析智能酒精壁炉不完全燃烧的成因及潜在问题 智能酒精壁炉作为一种环保、高效、现代化的取暖工具&#xff0c;其采用酒精作为燃料进行燃烧&#xff0c;但在一些情况下&#xff0c;可能会出现酒精燃烧不完全的问题。下面将深入探讨这一现象的成因以及可能引发的问题。 成因分析…