很多年前,刚开始接触到 ViewModel 概念的时候,将 DataModel 赋值给 ViewModel 的时候通常会这样做:
Id = x.Id,
ParentId = x.ParentId,
Name = x.Name,
Code = x.Code,
ChildCode = x.ChildCode,
Area = x.Area,
AuditId = x.AuditId,
AuditName = x.AuditName,
AuditTime = x.AuditTime,
IsBIM = x.IsBIM,
Status = x.Status,
SoftDeleted = x.SoftDeleted,
ConstructionUnit = x.ConstructionUnit,
ConstructionUnitId = x.ConstructionUnitId,
BuilderUnitNames = x.BuilderUnitNames,
BuilderUnitIds = x.BuilderUnitIds,
SupervisionUnit = x.SupervisionUnit,
SupervisionUnitId = x.SupervisionUnitId,
TestingUnit = x.TestingUnit,
TestingUnitId = x.TestingUnitId,
PremixedSupplier = x.PremixedSupplier,
PremixedSupplierId = x.PremixedSupplierId,
DesignUnit = x.DesignUnit,
DesignUnitId = x.DesignUnitId,
SurveyUnit = x.SurveyUnit,
SurveyUnitId = x.SurveyUnitId,
Address = x.Address,
Location = x.Location,
Image = x.Image,
ImageUploadTime = x.ImageUploadTime,
CreatedTime = x.CreatedTime,
上面的代码逻辑都是相同的,有多少字段都需要单独写出来。如果有新增或在修改删除字段的情况,还需要一一找到再做调整。所以当时就在网上找到了下面这段代码,实现的功能主要是将两个实体中字段名称相同,且类型相同的字段自动赋值,代码如下:
public static class ConvertHelper
{
/// <summary>
/// 两个相似实体转换
/// </summary>
/// <typeparam name="S">源实体</typeparam>
/// <typeparam name="T">赋值实体</typeparam>
/// <param name="source">源实体值</param>
/// <returns></returns>
public static T Merge<S, T>(this S source) where T : new()
{
if (source == null) return default(T);
var propertiesT = typeof(S).GetProperties(BindingFlags.Instance | BindingFlags.Public);
var propertiesL = typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public);
var entity = new T();
foreach (PropertyInfo itemL in propertiesL)
{
foreach (PropertyInfo itemT in propertiesT)
{
if (itemL.Name != itemT.Name || itemL.PropertyType != itemT.PropertyType) continue;
var value = itemT.GetValue(source, null);
itemL.SetValue(entity, value, null);
break;
}
}
return entity;
}
}
有了这个方法后,上面字段赋值的代码就可以用一行代码完成。从工作量上来看,这个代码是为我剩了不少。关于性能方面的问题,就暂时不在这里讨论。后面有机会再分享基于这个版本升级为带缓存的版本。
var project = projectDataModel.Merge<ProjectDataModel, ProjectViewModel>();