c# 如何如何自由转换两个沒有继承关系的字段及类型相同的实体模型
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
public class PersonDto
{
public string Name { get; set; }
public int Age { get; set; }
}
1.硬编码手动转换
Person p = new Person()
{
Age = 10,
Name = "張三"
};
PersonDto pd = new PersonDto()
{
Name = p.Name,
Age = p.Age
};
2.委托实现实体的相互转换
Person p = new Person()
{
Age = 10,
Name = "張三"
};
Func<Person, PersonDto> func = c => new PersonDto()
{
Age = c.Age,
Name = c.Name
};
PersonDto pd = func(p);
3. 使用AutoMapper完成不同实体的转换
Person p = new Person() { Age = 10, Name = "張三" };
Mapper.Initialize(m => m.CreateMap<Person, PersonDto>());
PersonDto pd = Mapper.Map<PersonDto>(p);
4.通过反射实现实体的相互转换
/// <summary>
/// 实体映射
/// </summary>
/// <typeparam name="TDestination">目标实体</typeparam>
/// <param name="source">源实体</param>
/// <returns></returns>
public static TDestination MapTo<TDestination>(object source) where TDestination : new()
{
TDestination dest = new TDestination();//创建目标对象
foreach (var p in dest.GetType().GetProperties())//獲取源实体所有的属性
{
p.SetValue(dest, source.GetType().GetProperty(p.Name)?.GetValue(source));//挨個為目標實體對應字段名進行賦值
}
return dest;
}
5. 通过Json反序列化实现实体的相互转换
首先通过nuget把Newtonsoft.Json引進來,然后coding...
Person p = new Person() { Age = 10, Name = "張三" };
PersonDto pd = JsonConvert.DeserializeObject<PersonDto>(JsonConvert.SerializeObject(p));
6.表达式树实现实体的相互转换
Person p = new Person() { Age = 10, Name = "張三" };
ParameterExpression parameterExpression = Expression.Parameter(typeof(Person), "p");
List<MemberBinding> memberBindingList = new List<MemberBinding>();//表示綁定的類派生自的基類,這些綁定用于對新創建對象的成員進行初始化(vs的注解。太生澀了,我這樣的小白解釋不了,大家將就著看)
foreach (var item in typeof(PersonDto).GetProperties()) //遍歷目標類型的所有屬性
{
MemberExpression property = Expression.Property(parameterExpression, typeof(Person).GetProperty(item.Name));//獲取到對應的屬性
MemberBinding memberBinding = Expression.Bind(item, property);//初始化這個屬性
memberBindingList.Add(memberBinding);
}
foreach (var item in typeof(PersonDto).GetFields())//遍歷目標類型的所有字段
{
MemberExpression property = Expression.Field(parameterExpression, typeof(Person).GetField(item.Name));//獲取到對應的字段
MemberBinding memberBinding = Expression.Bind(item, property);//同上
memberBindingList.Add(memberBinding);
}
MemberInitExpression memberInitExpression = Expression.MemberInit(Expression.New(typeof(PersonDto)), memberBindingList.ToArray());//初始化創建新對象
Expression<Func<Person, PersonDto>> lambda = Expression.Lambda<Func<Person, PersonDto>>(memberInitExpression, parameterExpression);
PersonDto pd = lambda.Compile()(p);
7.表达式树的封裝实现通用实体的相互转换
public static TDestination ExpressionTreeMapper<TSource, TDestination>(TSource source)
{
ParameterExpression parameterExpression = Expression.Parameter(typeof(TSource), "p");
List<MemberBinding> memberBindingList = new List<MemberBinding>();//表示綁定的類派生自的基類,這些綁定用于對新創建對象的成員進行初始化(vs的注解。太生澀了,我這樣的小白解釋不了,大家將就著看)
foreach (var item in typeof(TDestination).GetProperties()) //遍歷目標類型的所有屬性
{
MemberExpression property = Expression.Property(parameterExpression, typeof(TSource).GetProperty(item.Name));//獲取到對應的屬性
MemberBinding memberBinding = Expression.Bind(item, property);//初始化這個屬性
memberBindingList.Add(memberBinding);
}
foreach (var item in typeof(TDestination).GetFields())//遍歷目標類型的所有字段
{
MemberExpression property = Expression.Field(parameterExpression, typeof(TSource).GetField(item.Name));//獲取到對應的字段
MemberBinding memberBinding = Expression.Bind(item, property);//同上
memberBindingList.Add(memberBinding);
}
MemberInitExpression memberInitExpression = Expression.MemberInit(Expression.New(typeof(TDestination)), memberBindingList.ToArray());//初始化創建新對象
Expression<Func<TSource, TDestination>> lambda = Expression.Lambda<Func<TSource, TDestination>>(memberInitExpression, parameterExpression);
return lambda.Compile()(source); //拼裝是一次性的
}
8. 表达式树缓存实现通用实体的互换
实现思路:把每次编译后的表达式树缓存起來,如果存在,直接拿現成的编译好的表达式树调用就好了
/// <summary>
/// 生成表達式目錄樹。字典緩存
/// </summary>
public class ExpressionMapper
{
private static Dictionary<string, object> _dic = new Dictionary<string, object>();//緩存字典,緩存后的就是硬編碼所以性能高。
/// <summary>
/// 字典緩存表達式樹
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <typeparam name="TDestination"></typeparam>
/// <param name="source"></param>
/// <returns></returns>
public static TDestination Map<TSource, TDestination>(TSource source)
{
string key = $"funckey_{typeof(TSource).FullName}_{typeof(TDestination).FullName}";
if (!_dic.ContainsKey(key)) //如果該表達式不存在,則走一遍編譯過程
{
ParameterExpression parameterExpression = Expression.Parameter(typeof(TSource), "p");
List<MemberBinding> memberBindingList = new List<MemberBinding>();//表示綁定的類派生自的基類,這些綁定用于對新創建對象的成員進行初始化(vs的注解。太生澀了,我這樣的小白解釋不了,大家將就著看)
foreach (var item in typeof(TDestination).GetProperties()) //遍歷目標類型的所有屬性
{
MemberExpression property = Expression.Property(parameterExpression, typeof(TSource).GetProperty(item.Name));//獲取到對應的屬性
MemberBinding memberBinding = Expression.Bind(item, property);//初始化這個屬性
memberBindingList.Add(memberBinding);
}
foreach (var item in typeof(TDestination).GetFields())//遍歷目標類型的所有字段
{
MemberExpression property = Expression.Field(parameterExpression, typeof(TSource).GetField(item.Name));//獲取到對應的字段
MemberBinding memberBinding = Expression.Bind(item, property);//同上
memberBindingList.Add(memberBinding);
}
MemberInitExpression memberInitExpression = Expression.MemberInit(Expression.New(typeof(TDestination)), memberBindingList.ToArray());//初始化創建新對象
Expression<Func<TSource, TDestination>> lambda = Expression.Lambda<Func<TSource, TDestination>>(memberInitExpression, parameterExpression);
_dic[key] = lambda.Compile(); //拼裝是一次性的
}
return ((Func<TSource, TDestination>)_dic[key]).Invoke(source);
}
}
9. 表达式树泛型缓存实现通用实体的相互转换
/// <summary>
/// 生成表達式目錄樹 泛型緩存
/// </summary>
public class ExpressionGenericMapper
{
private static object func;
public static TDestination Map<TSource, TDestination>(TSource source)
{
if (func is null)//如果表達式不存在,則走一遍編譯過程
{
ParameterExpression parameterExpression = Expression.Parameter(typeof(TSource), "p");
var memberBindingList = new List<MemberBinding>();//表示綁定的類派生自的基類,這些綁定用于對新創建對象的成員進行初始化(vs的注解。太生澀了,我這樣的小白解釋不了,大家將就著看)
foreach (var item in typeof(TDestination).GetProperties()) //遍歷目標類型的所有屬性
{
MemberExpression property = Expression.Property(parameterExpression, typeof(TSource).GetProperty(item.Name));//獲取到對應的屬性
MemberBinding memberBinding = Expression.Bind(item, property);//初始化這個屬性
memberBindingList.Add(memberBinding);
}
foreach (var item in typeof(TDestination).GetFields())
{
MemberExpression property = Expression.Field(parameterExpression, typeof(TSource).GetField(item.Name));//獲取到對應的字段
MemberBinding memberBinding = Expression.Bind(item, property);//同上
memberBindingList.Add(memberBinding);
}
MemberInitExpression memberInitExpression = Expression.MemberInit(Expression.New(typeof(TDestination)), memberBindingList.ToArray());//初始化創建新對象
Expression<Func<TSource, TDestination>> lambda = Expression.Lambda<Func<TSource, TDestination>>(memberInitExpression, parameterExpression);
func = lambda.Compile();
}
return ((Func<TSource, TDestination>)func)(source); //拼裝是一次性的
}
}

浙公网安备 33010602011771号