WAutoMapper - qidot/YunstpNetCore GitHub Wiki
通过表达式拷贝变量
本文介绍了如何快速的复制一个类到另外一个类
在java的spring框架中经常会用到 BeanUtils.CopyProperties(from,target); 来实现目标类的快速赋值
在c#中,也有相对应的功能包,如:
- AutoMapper
- TinyMapper
在项目中呢,我参考了网上的相关资料后,改动成表达式来实现这个功能:
先看下通常情况下的赋值:
var a = new DtoA();
var b = new EntityA();
b.Id = a.Id;
b.Name = a.Name;
//或者是
var b = new EntityA{
Id = a.Id,
Name = a.Name
};
其实想法很简单,就是想少写一点代码,怎么实现呢
这里需要用到: lamda 来帮助我们实现了
定义WAutoMapper
详细请参见:
WAutoMapper.cs 复制帮助类
TestWorker.cs 测试用的实体
TestWorkerQueryDTO.cs 测试用的DTO
用法
我们分别用copy法与手工实例来进行测试,看看到底有什么区别
public IActionResult CopyExample([FromBody]TestWorkerQueryDTO testWorkerDTO)
{
Console.WriteLine($"dto=====>{testWorkerDTO.toJson()}");
Console.WriteLine($"复制实例");
var model = WAutoMapper<TestWorkerQueryDTO, TestWorker>.Map(testWorkerDTO);
Console.WriteLine($"model====>{model.toJson()}");
Console.WriteLine($"正常实例");
var model2 = new TestWorker
{
id = (int)testWorkerDTO.id,
createTime = testWorkerDTO.createTime,
name = testWorkerDTO.name,
age = testWorkerDTO.age
};
Console.WriteLine($"model====>{model2.toJson()}");
return Ok("ok");
}
看下实际的输出的表达式
发现TA其实就是用了
var b = new EntityA{
Id = a.Id,
Name = a.Name
};
int? 与 int 赋值
在.net中值类型是不能为空的,都会给上默认值,比如: int,long,DateTime等
刚开始的时候发现int?与int是不能赋值的,怎么处理呢,要判定一下
if (targetItem.PropertyType != sourceItem.PropertyType) {
//Nullable处理::::::System.Int32,System.Nullable`1[System.Int32]
//int与int? 或 int?与int
var targetTypeStr = targetItem.PropertyType.ToString();
var sourceTypeStr = sourceItem.PropertyType.ToString();
bool isSourceNullable = sourceTypeStr.StartsWith("System.Nullable", StringComparison.Ordinal)
&& sourceTypeStr.IndexOf(targetTypeStr, StringComparison.Ordinal) >= 0;
bool isTargetNullable = targetTypeStr.StartsWith("System.Nullable", StringComparison.Ordinal)
&&
targetTypeStr.IndexOf(sourceTypeStr, StringComparison.Ordinal) >= 0;
if (isSourceNullable || isTargetNullable) {
memberBindings.Add(Expression.Bind(targetItem, Expression.Convert(propertyExpression, targetItem.PropertyType)));
}
continue;
}
我们先注释掉这一段,来看下输出,你会发现相关差异
表达式变短了,缺少了相关属性,那是因为 int? 与 int的 type是不一致的,一个是Nullable<System.Int32> 一个是Int32这2个不等,所以被跳过
扩展
关于 int,long 数值大小类型的转换呢? 这个代码没有写,可能会遇到此类情景
效率对比
请看文章::: https://www.cnblogs.com/castyuan/p/9285101.html
具体测试我没有做,感兴趣的同学可以自己去实践一下。