我在名称空间GDeerParkEntity下有一个名为Buseartag的实体,下面是架构:
namespace GDeerParkEntity
{
public class Buseartag
{
public Guid Eartag_id { get; set; } //pk
public String Eartag_code { get; set; }
public Nullable<Guid> Sex_id { get; set; }
public Nullable<Guid> Breed_id { get; set; }
public Nullable<Guid> Primarily_id { get; set; }
public Nullable<Guid> Bas_deerpen_id { get; set; }
public String Chip_num { get; set; }
public String Eartag_note { get; set; }
}
}
我还在同一名称空间GDeerParkEntity下面有另一个名为Busremove的实体,其中包含Buseartag:
namespace GDeerParkEntity
{
public class Busremove
{
public Guid Removeid { get; set; }
public Nullable<Guid> Eartagid { get; set; }
public string Removereason { get; set; }
public DateTime Removetime { get; set; }
public Guid Suppenid { get; set; }
public Guid Subpenid { get; set; }
public string Removenote { get; set; }
public Buseartag BuseartagModel { get; set; }
}
}
但是现在,在客户端,我有另外两个实体,其名称与上面相同,但名称空间不同。
namespace ServiceProxy
{
public class Buseartag
{
public Guid Eartag_id { get; set; } //pk
public String Eartag_code { get; set; }
public Nullable<Guid> Sex_id { get; set; }
public Nullable<Guid> Breed_id { get; set; }
public Nullable<Guid> Primarily_id { get; set; }
public Nullable<Guid> Bas_deerpen_id { get; set; }
public String Chip_num { get; set; }
public String Eartag_note { get; set; }
}
}
===================================================
namespace ServiceProxy
{
public class Busremove
{
public Guid Removeid { get; set; }
public Nullable<Guid> Eartagid { get; set; }
public string Removereason { get; set; }
public DateTime Removetime { get; set; }
public Guid Suppenid { get; set; }
public Guid Subpenid { get; set; }
public string Removenote { get; set; }
public Buseartag BuseartagModel { get; set; }
}
}
所以我想通过使用反射将GDeerParkEntity.Busremove实体转换为ServiceProxy.Busremove实体(因为有很多像这样的实体应该被转换,所以我使用T来覆盖这些场景):
public class Utils
{
public static T ConvertFromEntity<T, T1>(T1 t1)
{
if (t1 == null) return default(T);
Type type = typeof(T);
Type typeEx = typeof(T1);
PropertyInfo[] infoT = type.GetProperties();
PropertyInfo[] infoT1 = typeEx.GetProperties();
T t= Activator.CreateInstance<T>();
foreach (PropertyInfo pT in infoT)
{
string pTName = pT.Name;
foreach (PropertyInfo pT1 in infoT1)
{
try
{
if (pT1.Name.Equals(pTName))
{
if (!pT1.Name.ToLower().Contains("model"))
{
object pT1Value = pT1.GetValue(t1, null);
pT.SetValue(t as object, pT1Value, null);
break;
}
else
{
//How should I do here to convert Buseartag?
}
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
}
return t;
}
用法如下:
ServiceProxy.Busremove bus = Utils.ConvertFromEntity<ServiceProxy.Busremove, GDeerParkEntity.Busremove>(remove);
但是现在我在Busremove实体内转换Buseartag时有困难,任何人都可以帮助我吗?谢谢。 我尝试过type.getnestedtypes(),但它对我不起作用。
答案 0 :(得分:1)
这样的东西有一个库 - AutoMapper。它被广泛使用,开源和经过充分测试。您可以使用NuGet安装它。 它用几行代码解决了你的问题:
using AutoMapper;
static class EntityConverter
{
static EntityConverter()
{
AutoMapper.Mapper.CreateMap<GDeerParkEntity.Busremove, ServiceProxy.Busremove>();
AutoMapper.Mapper.CreateMap<GDeerParkEntity.Buseartag, ServiceProxy.Buseartag>();
AutoMapper.Mapper.CreateMap<ServiceProxy.Busremove, GDeerParkEntity.Busremove>();
AutoMapper.Mapper.CreateMap<ServiceProxy.Buseartag, GDeerParkEntity.Buseartag>();
}
public static TDestination Convert<TSource, TDestination>(TSource source)
{
return AutoMapper.Mapper.Map<TSource, TDestination>(source);
}
}
var sourceEntity = new GDeerParkEntity.Busremove()
var convertedEntity = EntityConverter.Convert<GDeerParkEntity.Busremove, ServiceProxy.Busremove>(sourceEntity);
如果您仍想重新发明轮子,可以保留类型映射的组合并检查属性值是否可以映射到其他类型:
static class EntityConverter
{
private static Dictionary<Type, Type> _mappings =
new Dictionary<Type, Type>()
{
{ typeof(GDeerParkEntity.Busremove), typeof(ServiceProxy.Busremove) },
{ typeof(GDeerParkEntity.Buseartag), typeof(ServiceProxy.Buseartag) },
{ typeof(ServiceProxy.Busremove), typeof(GDeerParkEntity.Busremove) },
{ typeof(ServiceProxy.Buseartag), typeof(GDeerParkEntity.Buseartag) },
};
private static object ConvertEntity(object source, Type targetType)
{
var target = Activator.CreateInstance(targetType);
TransferValues(source, target);
return target;
}
private static void TransferValues(object source, object target)
{
var sourceProperties = source.GetType().GetProperties();
var targetProperties = target.GetType().GetProperties();
foreach(var srcProperty in sourceProperties)
{
var targetProperty = targetProperties.FirstOrDefault(p => p.Name == srcProperty.Name);
if(targetProperty == null)
{
continue;
}
object value = srcProperty.GetValue(source);
if(_mappings.ContainsKey(srcProperty.PropertyType))
{
value = ConvertEntity(value, _mappings[srcProperty.PropertyType]);
}
targetProperty.SetValue(target, value);
}
}
public static TDestination ConvertEntity<TSource, TDestination>(TSource source)
{
var destination = Activator.CreateInstance<TDestination>();
TransferValues(source, destination);
return destination;
}
}
用法与AutoMapper相同。
答案 1 :(得分:0)
嗯,我认为你需要的是这些实体的某种通用接口 然后你可以去..
if (pT1Value is IMyCommonEntityInterface)
{
... this bit is tricky ....
}
棘手的一点将涉及: - 1.根据命名约定,将子实体的名称转换为需要转换为的实体类型的名称。 2.按名称获取Type对象 3.对通用ConvertFromEntity方法进行递归调用,传递子实体类型和转换后的子实体类型,当然还有子项的值
C# call Generic method dynamically
这可能会帮助你。