C#--Mapster(高性能映射)用法

news2024/11/20 1:34:37

1.Nuget安装Mapster包引用

2.界面XAML部分

<Window x:Class="WpfApp35.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp35"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Button Content="1.简单映射" HorizontalAlignment="Left" Margin="345,145,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_1" Height="52"/>
        <Button Content="2.复杂映射" HorizontalAlignment="Left" Margin="345,235,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_2" Height="52"/>
        <Button Content="3.映射扩展" HorizontalAlignment="Left" Margin="345,320,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_3" Height="52"/>
    </Grid>
</Window>

3.脚本.cs部分 

using Mapster;
using MapsterMapper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Expression = System.Linq.Expressions.Expression;

namespace WpfApp35
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            // 全局配置
            //TypeAdapterConfig.GlobalSettings.Default.CamelCase(true); // 将属性名称转换为小驼峰命名
        }

        //软件框架搭建  wpf+efcore+ct(CommunityToolkit)+s7net+mapster

        //1.简单映射
        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            //阶段一  简单使用阶段部分  Student==>StudentDto
            //上面简单映射,但是类StudentDto中的CourceName属性没有被映射,通过下面方法可对属性设置匹配关系,给CourceName属性映射
            Student stu = new Student();
            stu.AGE = 25;
            stu.ID = "1";
            stu.CID = "321281199505290919";
            stu.NAME = "陈兆杰";
            Cource cource = new Cource();
            cource.ID = "1";
            cource.CourceName = "数学";
            cource.Grade = 80.56;
            stu.Cource = cource;
            StudentDto stuDto = new StudentDto();
            {
                //方法一:
                stuDto = stu.Adapt<StudentDto>();//stu实例映射为StudentDto类型
                MessageBox.Show($"stuDto.CourceName: {stuDto.CourceName}");

                //方法二:
                stu.Adapt(stuDto);//stu实例映射为stuDto实例,相同的名称字段属性将会自动映射
                MessageBox.Show($"stuDto.CourceName: {stuDto.CourceName}");

                //方法三:
                IMapper mapper = new Mapper();
                stuDto = mapper.Map<StudentDto>(stu);// stu实例映射为StudentDto类型
                MessageBox.Show($"stuDto.CourceName: {stuDto.CourceName}");

                //方法四:
                mapper.Map(stu, stuDto);//stu实例映射为stuDto实例,相同的名称字段属性将会自动映射
                MessageBox.Show($"stuDto.CourceName: {stuDto.CourceName}");
            }
        }

        //2.复杂映射
        private void Button_Click_2(object sender, RoutedEventArgs e)
        {
            //阶段二  复杂映射  Student==>StudentDto
            Student stu = new Student();
            stu.AGE = 25;
            stu.ID = "1";
            stu.CID = "321281199505290919";
            stu.NAME = "陈兆杰";
            Cource cource = new Cource();
            cource.ID = "1";
            cource.CourceName = "数学";
            cource.Grade = 80.56;
            stu.Cource = cource;

            StudentDto stuDto = new StudentDto();
            {
                TypeAdapterConfig config = new TypeAdapterConfig();
                //建立映射关系一, NewConfig 删除任何现有配置
                {
                    //配置里面设置强行绑定项部分
                    config.NewConfig<Student, StudentDto>()
                     .Map(dto => dto.ID, d => d.ID).Map(dto => dto.NAME, d => d.NAME).Map(dto => dto.CourceName, s => s.Cource.CourceName);
                }
                //建立映射关系二,而 ForType 创建或增强配置。
                {
                    //        config.ForType<Student, StudentDto>()
                    //.Map(dto => dto.ID, d => d.ID).Map(dto => dto.NAME, d => d.NAME).Map(dto => dto.CourceName, s => s.Cource.CourceName);
                }
                stuDto = stu.Adapt<StudentDto>(config);//根据config配置,映射stu实体为StudentDto类型
                MessageBox.Show($"stuDto.CourceName: {stuDto.CourceName}");
            }
        }

        //映射扩展
        private void Button_Click_3(object sender, RoutedEventArgs e)
        {
            Student stu = new Student
            {
                age = 25,
                id = 1,
                name = "陈兆杰111",
                classes = classes
            };

            StudentDto StuDto1 = ExpressionMapper.Mapper(stu, s => new StudentDto
            {
                classesName = s.classes.name,
            });
        }
        /// <summary>
        /// 可以处理复杂映射
        /// </summary>
        /// <typeparam name="TIn">输入类</typeparam>
        /// <typeparam name="TOut">输出类</typeparam>
        /// <param name="expression">表达式目录树,可以为null</param>
        /// <param name="tIn">输入实例</param>
        /// <returns></returns>
        public static TOut Mapper<TIn, TOut>(TIn tIn, Expression<Func<TIn, TOut>> expression = null)
        {
            ParameterExpression parameterExpression = null;
            List<MemberBinding> memberBindingList = new List<MemberBinding>();
            parameterExpression = Expression.Parameter(typeof(TIn), "p");

            if (expression != null)
            {
                parameterExpression = expression.Parameters[0];
                if (expression.Body != null)
                {
                    memberBindingList.AddRange((expression.Body as MemberInitExpression).Bindings);
                }
            }
            foreach (var item in typeof(TOut).GetProperties())
            {
                if (typeof(TIn).GetProperty(item.Name) != null)
                {
                    MemberExpression property = Expression.Property(parameterExpression, typeof(TIn).GetProperty(item.Name));
                    MemberBinding memberBinding = Expression.Bind(item, property);
                    memberBindingList.Add(memberBinding);
                }
                if (typeof(TIn).GetField(item.Name) != null)
                {
                    MemberExpression property = Expression.Field(parameterExpression, typeof(TIn).GetField(item.Name));
                    MemberBinding memberBinding = Expression.Bind(item, property);
                    memberBindingList.Add(memberBinding);
                }
            }
            foreach (var item in typeof(TOut).GetFields())
            {
                if (typeof(TIn).GetField(item.Name) != null)
                {
                    MemberExpression property = Expression.Field(parameterExpression, typeof(TIn).GetField(item.Name));
                    MemberBinding memberBinding = Expression.Bind(item, property);
                    memberBindingList.Add(memberBinding);
                }
                if (typeof(TIn).GetProperty(item.Name) != null)
                {
                    MemberExpression property = Expression.Property(parameterExpression, typeof(TIn).GetProperty(item.Name));
                    MemberBinding memberBinding = Expression.Bind(item, property);
                    memberBindingList.Add(memberBinding);
                }
            }
            MemberInitExpression memberInitExpression = Expression.MemberInit(Expression.New(typeof(TOut)), memberBindingList.ToArray());

            Expression<Func<TIn, TOut>> lambda = Expression.Lambda<Func<TIn, TOut>>(memberInitExpression, new ParameterExpression[]
            {
                    parameterExpression
            });
            Func<TIn, TOut> func = lambda.Compile();//获取委托
            return func.Invoke(tIn);
        }
    }

    public class Student
    {
        public string ID { get; set; }
        public string NAME { get; set; }
        public int AGE { get; set; }
        public string CID { get; set; }
        public Cource Cource { get; set; }
    }
    public class Cource
    {
        public string ID { get; set; }
        public string CourceName { get; set; }
        public double Grade { get; set; }
    }

    public class StudentDto
    {
        public string ID { get; set; }
        public string NAME { get; set; }
        public string CourceName { get; set; }
    }
}

4.小结 

        Mapster库是一个用于对象映射的工具,它的作用就像是帮助你把一个对象中的数据复制到另一个对象中。简单来说,当你需要把一个类的数据转换成另一个类的数据时,Mapster可以帮助你快速、方便地实现这个转换过程,省去了手动赋值的繁琐工作。这对于在应用程序中处理不同类型对象之间的数据转换非常有用,让你可以更轻松地管理和操作数据。

应用场景:

        当你开发一个电子商务网站时,假设你有一个名为 Product 的类,表示网站上的商品信息,包括商品名称、价格、描述等属性。另外你还有一个名为 ProductViewModel 的类,表示在网页上展示商品信息所需的属性,比如显示的商品名称、价格、缩略图等。

你可以使用 Mapster 库来处理这两个类之间的数据映射。比如,当你从数据库中查询到了 Product 对象,想要在网页上展示商品信息时,你可以使用 Mapster 来将 Product 对象映射成 ProductViewModel 对象,这样就可以方便地在网页上展示商品信息,而不需要手动复制每个属性的数值。

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

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

相关文章

实战指南:Vue 2基座 + Vue 3 + Vite + TypeScript微前端架构实现动态菜单与登录共享

实战指南&#xff1a;Vue 2基座 Vue 3 Vite TypeScript子应用vue2微前端架构实现动态菜单与登录共享 导读&#xff1a; 在当今的前端开发中&#xff0c;微前端架构已经成为了一种流行的架构模式。本文将介绍如何结合Vue 2基座、Vue 3子应用、Vite构建工具和TypeScript语言…

华为机考入门python3--(32)牛客32-密码截取

分类&#xff1a;最长对称子串、动态规划 知识点&#xff1a; 生成二维数组 dp [[0] * n for _ in range(n)] 求最大值 max(value1, value2) 动态规划的步骤 a. 定义问题 长度为n下最长的对称子串的长度 b. 确定状态 dp[i][j]表示字符串从索引i到j的子串是否为对称…

2024.5.28晚训题解

提前预告&#xff0c;市赛初中组会考算法题&#xff0c;应该会有两道模板题 比如DFS BFS 二分 简单动态规划&#xff0c;虽然我们没学多久&#xff0c;但是模板题你还是要会写的 A题 编辑距离 动态规划 注意多组输入 #include<iostream> using namespace std; int dp[1…

unity3D获取某天的0点和23点59分59秒

系列文章目录 unity工具 文章目录 系列文章目录unity工具 &#x1f449;一、前言&#x1f449;二、获取某一天的0点和23点59分59秒1-1.代码如下1-2.调用方法如下1-2-1.获取当天的时间1-2-2.获取某一天的时间 &#x1f449;三、当月第一天0时0分0秒&#x1f449;四、当月最后一…

SHELL编程(三)网络基础命令 Makefile

目标 一、网络基础及相关命令&#xff08;一&#xff09;网络相关命令&#xff08;二&#xff09;重启网络服务 二、Makefile&#xff08;一&#xff09;标签式语法&#xff08;二&#xff09;目标:依赖 式语法1. 格式2. 编译流程&#xff1a;预处理 编译 汇编 链接3. 目标和伪…

TiDB-从0到1-体系结构

TiDB从0到1系列 TiDB-从0到1-体系结构TiDB-从0到1-分布式存储TiDB-从0到1-分布式事务 一、TiDB体系结构图 TiDB基础的体系架构中有4大组件 TiDB Server&#xff1a;用于处理客户端的请求PD&#xff1a;体系的大脑&#xff0c;存储元数据信息TiKV&#xff1a;存储数据TiFlash…

Stable Diffusion 模型演进:LDM、SD 1.0, 1.5, 2.0、SDXL、SDXL-Turbo 等

节前&#xff0c;我们星球组织了一场算法岗技术&面试讨论会&#xff0c;邀请了一些互联网大厂朋友、参加社招和校招面试的同学。 针对算法岗技术趋势、大模型落地项目经验分享、新手如何入门算法岗、该如何准备、面试常考点分享等热门话题进行了深入的讨论。 合集&#x…

Vue3+Ant design 实现Select下拉框一键全选/清空

最近在做后台管理系统项目的时候&#xff0c;产品增加了一个让人非常苦恼的需求&#xff0c;让在Select选择器中添加一键全选和清空的功能&#xff0c;刚开始听到的时候真是很懵&#xff0c;他又不让在外部增加按钮&#xff0c;其实如果说在外部增加按钮实现全选或者清空的话&a…

触摸屏是输入设备还是输出设备?

从功能上讲&#xff0c;触摸屏理应属于输入设备&#xff0c;之所以有很多用户会误会它是输出设备&#xff0c;是因为将其与“触摸显示屏”搞混了&#xff0c;以手机屏幕为例&#xff0c;它并不是单层屏幕&#xff0c;而是有多个不同功能和作用组成的集成屏&#xff0c;这类带有…

ubuntu-24.04系统静态Mac和IP配置

操作系统版本&#xff08;桌面版&#xff09;&#xff1a;ubuntu-24.04-desktop-amd64.iso 原因说明&#xff1a;因网络的IP地址和Mac是预分配的&#xff0c;所以ubuntu系统需要修改网卡的mac地址和IP才能访问&#xff0c;网络查了半天资料都没成功&#xff0c;后再界面提示&a…

【Python】 Python中的“命名元组”:简单而强大的数据结构

基本原理 在Python中&#xff0c;namedtuple是tuple的一个子类&#xff0c;它允许我们为元组的每个位置指定一个名字。这种数据结构非常适合用于需要固定字段和值的场景&#xff0c;例如数据库查询的结果或配置文件中的设置。 namedtuple提供了一种方便的方式来访问元组中的元…

力扣2028. 找出缺失的观测数据

题目&#xff1a; 现有一份 n m 次投掷单个 六面 骰子的观测数据&#xff0c;骰子的每个面从 1 到 6 编号。观测数据中缺失了 n 份&#xff0c;你手上只拿到剩余 m 次投掷的数据。幸好你有之前计算过的这 n m 次投掷数据的 平均值 。 给你一个长度为 m 的整数数组 rolls &a…

防止浏览器缓存了静态的配置等文件(例如外部的config.js 等文件)

防止浏览器缓存了静态的配置文件 前言1、在script引入的时候添加随机数1.1、引入js文件1.2、引入css文件2、通过html文件的<meta>设置防止缓存3、使用HTTP响应头:前言 在实际开发中浏览器的缓存问题一直是一个很让人头疼的问题,尤其是我们打包时候防止的静态配置文件c…

在 PhpStorm 中自定义代码片段

在 PhpStorm 中自定义代码片段的步骤如下: 打开 PhpStorm,进入 “File” > “Settings” > “Editor” > “Live Templates”。 在右侧面板中,点击 “” 号,选择 “Live Template”。 在弹出的窗口中: Abbreviation: 输入您想要自动补全的缩写,比如 “de”Template …

【强训笔记】day24

NO.1 思路&#xff1a;递归。 代码实现&#xff1a; class Solution { public:bool IsBalanced_Solution(TreeNode* pRoot) {return dfs(pRoot)!-1;}int dfs(TreeNode* root){if(rootnullptr) return 0;int leftdfs(root->left);if(left-1) return -1;int rightdfs(root-…

深度揭秘:蓝海创意云渲染农场的五大特色功能

在当今数字化时代&#xff0c;影视制作、效果图设计等领域对于高质量的渲染需求日益增长。在这个背景下&#xff0c;云渲染平台成为了行业中不可或缺的一部分&#xff0c;它为用户提供了高效、灵活的渲染解决方案。蓝海创意云渲染农场https://www.vsochina.com/cn/render蓝海创…

WWW24因果论文(1/8) | 利用强化学习(智能体)进行因果问答

【摘要】因果问题询问不同事件或现象之间的因果关系。它们对于各种用例都很重要&#xff0c;包括虚拟助手和搜索引擎。然而&#xff0c;许多当前的因果问答方法无法为其答案提供解释或证据。因此&#xff0c;在本文中&#xff0c;我们旨在使用因果关系图来回答因果问题&#xf…

昂科烧录器支持Infineon英飞凌的磁性位置传感器TLE4998S8D

芯片烧录行业领导者-昂科技术近日发布最新的烧录软件更新及新增支持的芯片型号列表&#xff0c;其中Infineon英飞凌的磁性位置传感器TLE4998S8D已经被昂科的通用烧录平台AP8000所支持。 TLE4998S8D是一款磁性位置传感器&#xff0c;经过专门设计&#xff0c;满足高精度角度和位…

实施阶段(2024年5月)

【项目活动1】斐波拉契数列第n项的值&#xff1f; 数学思想&#xff1a;第一项和第二项的值都为1&#xff0c;从第三项开始值为前两项的和。 方法一&#xff1a;迭代 迭代变量&#xff1a;f1和f2 迭代表达式&#xff1a;f1,f2f2,f1f2 计数器&#xff1a;i 迭代表达式运算…

webpack打包配置项

webpack打包配置项 在config.js 中 module.exports {publicPath: process.env.NODE_ENV production ? / : /, //静态资源目录outputDir: dist, //打包名称assetsDir: static,//静态资源&#xff0c;目录devServer: {port: port,open: false,overlay: {warnings: false,erro…