我有以下嵌套输入类
//InputClass
public class MessageViewModel
{
public bool IsSelected { get; set; }
public string Subject { get; set; }
public DateTime CreationDate { get; set; }
public List<MessageViewModel> Messages { get; set; }
}
我想创建以下类型的新实例:
//Target Class
public class DestinationClass
{
public string Subject { get; set; }
}
对于具有属性IsSelected = true的每个实例MessageViewModel 在这种情况下,最佳解决方案是什么?这可以使用AutoMapper来实现吗?
编辑:
假设我有以下对象:
var vm = new MessageViewModel
{
Messages = new List<MessageViewModel> {
new MessageViewModel {
IsSelected = true,
Messages = new List<MessageViewModel> {
new MessageViewModel { IsSelected = true,
Messages = new List<MessageViewModel> { new MessageViewModel { },
new MessageViewModel { },
new MessageViewModel { } } } } } }
};
我想遍历它,只提取并映射IsSelected等于true的MessageViewModels。
求助:
使用以下代码:
public static class TraversalHelper
{
public static void TraverseAndExecute<T>(this T composite, Func<T, IEnumerable<T>> selectChildren, Action<T> action)
where T : class
{
action.Invoke(composite);
composite.TraverseAndExecute(selectChildren, action, new List<T> { composite });
}
private static void TraverseAndExecute<T>(this T composite, Func<T, IEnumerable<T>> selectChildren, Action<T> action, IList<T> invokedComponents)
where T : class
{
invokedComponents = invokedComponents ?? new List<T>();
var components = selectChildren(composite) ?? new T[] { };
foreach (var component in components)
{
if (!invokedComponents.Contains(component))
{
action.Invoke(component);
invokedComponents.Add(component);
component.TraverseAndExecute(selectChildren, action, invokedComponents);
}
else
{
}
}
}
}
我设法迭代了我的分层对象:
var vm = new MessageViewModel
{
Messages = new List<MessageViewModel> {
new MessageViewModel {
IsSelected = true,
Messages = new List<MessageViewModel> {
new MessageViewModel {
IsSelected = true,
Messages = new List<MessageViewModel> {
new MessageViewModel { },
new MessageViewModel { },
new MessageViewModel { } } } } } }
};
var results = new List<DestinationClass>();
vm.TraverseAndExecute(_ => _.Messages, _ => {
if(_.IsSelected == true)
{
results.Add(new DestinationClass { Subject = _.Subject });
}
});
答案 0 :(得分:2)
由于您的类是嵌套层次结构,因此您需要一个扩展方法。
具有更多LINQ特征的一个将是:
public static IEnumerable<T> Flatten<T>(this T current, Func<T, IEnumerable<T>> childrenFn) {
var working = new Stack<T>();
working.Push(current);
while (working.Count > 0) {
current = working.Pop();
yield return current;
if (childrenFn(current) != null)
foreach (var child in childrenFn(current))
working.Push(child);
}
}
这将获取一个父对象和一个从父对象返回子对象列表的函数,并返回所有被展平的对象。
现在您可以使用它来产生答案:
var ans = vm.Flatten(mvm => mvm.Messages)
.Where(mvm => mvm.IsSelected)
.Select(mvm => new DestinationClass() { Subject = mvm.Subject });
答案 1 :(得分:0)
在这种情况下,我将使用IEnumerable的Message ViewModel作为DestinationClass中的构造函数参数。然后,您可以使用System.Linq迭代MessageViewModels集合,并选择条件为true的每个模型,并将其转换为IEnumerable of DestinationClass。
这只是解决此问题的一种方法。如果您可以向我们提供有关您的解决方案架构的更多详细信息,我们将更容易为您提供支持。问候EnvyIT