编辑:这原本是1:1映射,但我想通了,我需要一个更复杂的递归映射,这样一个新的问题被张贴在这里:How to recursively map entity to view model with Automapper function call?如何自动将.NET函数调用映射到属性?
我想一般映射实体类功能到视图模型,使用ServiceStack ConvertTo <>方法。这映射所有相似的类型和属性名称,并且工作正常,但我想找到一种方法将函数的结果映射到属性。下面是一些代码
实体例如:
public class Item {
public long Id {get; set;}
public List<Product> GetProducts() {
return Repository.GetAll<Product>();
}
}
视图模型例如:
public class ItemViewModel {
public long Id {get;set;}
public List<Product> Products {get; set;}
}
理想的结果将是有一个地图功能,着眼于实体类的匹配方法返回类型,函数名称是“Get”+属性名称,然后执行它并将结果映射到视图模型。
public TTarget MapToViewModel<TSource, TTarget>(TSource source)
where TTarget : new()
{
var sourceType = source.GetType();
var targetProperties = typeof(TTarget).GetProperties(BindingFlags.Public | BindingFlags.Instance);
var sourceProperties = sourceType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
var sourceMethods = sourceType.GetMethods(BindingFlags.Public | BindingFlags.Instance);
var target = Activator.CreateInstance<TTarget>();
foreach (var prop in targetProperties)
{
var sourceProp = sourceProperties.FirstOrDefault(x => x.Name == prop.Name);
if (sourceProp != null)
{
prop.SetValue(target, sourceProp.GetValue(source, null), null);
}
else
{
var sourceMethod = sourceMethods.FirstOrDefault(x => x.Name == "Get" + prop.Name);
if (sourceMethod != null)
{
prop.SetValue(target, sourceMethod.Invoke(source, null), null);
}
}
}
return target;
}
在上面的.FirstOrDefault
调用的条件:
谢谢,我得到了这个工作。现在我有另一个困境。做这个递归有多难?例如,如果Product类有一个属性List图像,我需要从Product类调用GetImages()? –
user3092978
我真的没有看到这将需要一个递归调用。你的意思是,如果方法和属性都存在于一个对象上,那么该方法需要调用?如果是这样的话,你可以切换属性和方法的if语句来首先检查方法。 – valverij
不完全,我的意思是如果映射对象具有需要通过调用另一个函数来映射的另一个属性。你的回答帮助我确定我需要一些更复杂的东西,看起来像Automapper可能能够处理。我问另一个问题在这里http://stackoverflow.com/questions/20573600/how-to-recursively-map-entity-to-view-model-with-automapper-function-call – user3092978