C# AutoMapper是否也应用作形状重新映射工具

C# AutoMapper是否也应用作形状重新映射工具,c#,viewmodel,automapper,dto,C#,Viewmodel,Automapper,Dto,我知道AutoMapper只是在两个对象之间映射属性 Automapper不用于重塑数据,我认为必须对其进行编程 我有一个PeriodDTO.IEnumerable,需要将其重塑为PeriodListViewModel.List 每个CellViewModel都包含一个列表 这不是一对一的映射,我想也许这不应该被映射,因为这是不可能的- public class PeriodRequest { public IEnumerable<Period> Period

我知道AutoMapper只是在两个对象之间映射属性

Automapper不用于重塑数据,我认为必须对其进行编程

我有一个
PeriodDTO.IEnumerable
,需要将其重塑为
PeriodListViewModel.List

每个
CellViewModel
都包含一个
列表

这不是一对一的映射,我想也许这不应该被映射,因为这是不可能的-

public class PeriodRequest
    {
        public IEnumerable<Period> Periods { get; set; }
        public IEnumerable<DateTime> Weeks { get; set; }
    }

public class PeriodListViewModel
{       
    public PeriodListViewModel(IEnumerable<Period> periods)
    {
        CellViewModels = new List<CellViewModel>();
        var groupedPeriods = periods.GroupBy(p => p.LessonNumber).OrderBy(p => p.Key).ToList();
        foreach (var groupedPeriod in groupedPeriods)
        {
            var cellViewModel = new CellViewModel();
            CellViewModels.Add(cellViewModel);
            foreach (var period in groupedPeriod)
            {
                var rowViewModel = new RowViewModel();
                rowViewModel.Content = period.Content;
                rowViewModel.SchoolclassCode = period.SchoolclassCode;
                rowViewModel.DayName = period.LessonDate.ToShortDateString();
                rowViewModel.DayIndex = (int)period.LessonDate.DayOfWeek;
                rowViewModel.LessonNumber = period.LessonNumber;
                cellViewModel.Rows.Add(rowViewModel);
            }
        }
    }
    public List<CellViewModel> CellViewModels { get; set; }
}

public class CellViewModel
    {
        public CellViewModel()
        {
            Rows = new List<RowViewModel>();
        }
        public List<RowViewModel> Rows { get; set; }
    }

public class RowViewModel
    {
        public string DayName { get; set; }
        public string SchoolclassCode { get; set; }
        public string Content { get; set; }
        public int DayIndex { get; set; }
        public int LessonNumber { get; set; }
    }

public class Period
    {
        public int PeriodId { get; set; }
        public DateTime LessonDate { get; set; }
        public int LessonNumber { get; set; }
        public string SchoolclassCode { get; set; }
        public string Content { get; set; }
        public int SchoolyearId { get; set; }
        public Schoolyear Schoolyear { get; set; }
...
}
公共类请求
{
公共IEnumerable句点{get;set;}
公共IEnumerable Weeks{get;set;}
}
公共类周期列表视图模型
{       
公共时段列表视图模型(IEnumerable periods)
{
CellViewModels=新列表();
var groupedPeriods=periods.GroupBy(p=>p.LessonNumber).OrderBy(p=>p.Key).ToList();
foreach(groupedPeriods中的var groupedPeriod)
{
var cellViewModel=新的cellViewModel();
添加(cellViewModel);
foreach(groupedPeriod中的var期间)
{
var rowViewModel=新的rowViewModel();
rowViewModel.Content=句点.Content;
rowViewModel.SchoolclassCode=period.SchoolclassCode;
rowViewModel.DayName=period.LessonDate.ToSortDateString();
rowViewModel.DayIndex=(int)period.LessonDate.DayOfWeek;
rowViewModel.LessonNumber=句点.LessonNumber;
cellViewModel.Rows.Add(rowViewModel);
}
}
}
公共列表CellViewModels{get;set;}
}
公共类CellViewModel
{
公共CellViewModel()
{
行=新列表();
}
公共列表行{get;set;}
}
公共类RowViewModel
{
公共字符串DayName{get;set;}
公共字符串类代码{get;set;}
公共字符串内容{get;set;}
public int DayIndex{get;set;}
public int LessonNumber{get;set;}
}
公课期间
{
公共整型周期ID{get;set;}
public DateTime LessonDate{get;set;}
public int LessonNumber{get;set;}
公共字符串类代码{get;set;}
公共字符串内容{get;set;}
public int SchoolyearId{get;set;}
公立学年{get;set;}
...
}

目前,PeriodListViewModel可以很容易地进行单元测试。我现在在问自己,AutoMapper如何使情况变得更好?

几个月来,我主要使用AutoMapper从实体模型创建视图模型,基本上就是您在那里所做的。我曾使用AutoMapper展平和取消展平非常复杂的模型


但我个人不会在视图模型的构造函数中这样做。原因是PeriodListViewModel的来源可能不同。这个想法是,一旦你创建/配置了映射器,你可以随意地做
Mapper.Map几个月来,我主要使用AutoMapper从实体模型创建视图模型,基本上就是你在那里做的。我曾使用AutoMapper展平和取消展平非常复杂的模型


但我个人不会在视图模型的构造函数中这样做。原因是PeriodListViewModel的来源可能不同。其思想是,一旦您创建/配置了映射器,您就可以随意执行
Mapper.Map,虽然您没有从
IEnumerable
List
的简单的1:1映射,但您仍然可以通过仅在类与类之间联系的地方使用Automapper,从Automapper中获得一些值,在您的示例中,它介于
期间
行视图模型
之间

考虑到这一点,您还可以更好地利用LINQ,并在一次扫掠运动中完成所有工作,前提是您设置了需要从
Period
RowViewModel
重新成形的投影

下面是一个控制台代码示例,它正好演示了这一点。请注意,我们通过
ValueResolve
使用Automapper的解析器类概念进行重新整形,并且我在
CellViewModel
中添加了一个额外的构造函数来接受
IEnumerable
,这有助于改进我们的声明

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using AutoMapper;

namespace GroupingMapping
{
    public class PeriodRequest
    {
        public IEnumerable<Period> Periods { get; set; }
        public IEnumerable<DateTime> Weeks { get; set; }
    }

    public class RowViewModel
    {
        public string DayName { get; set; }
        public string SchoolclassCode { get; set; }
        public string Content { get; set; }
        public int DayIndex { get; set; }
        public int LessonNumber { get; set; }
    }

    public class Period
    {
        public int PeriodId { get; set; }
        public DateTime LessonDate { get; set; }
        public int LessonNumber { get; set; }
        public string SchoolclassCode { get; set; }
        public string Content { get; set; }
        public int SchoolyearId { get; set; }
        // No definition provided for Schoolyear
        //public Schoolyear Schoolyear { get; set; }
    }

    public class CellViewModel
    {
        public CellViewModel()
        {
            Rows = new List<RowViewModel>();
        }

        public CellViewModel(IEnumerable<RowViewModel> rowVMSet)
        {
            Rows = new List<RowViewModel>(rowVMSet);
        }

        public List<RowViewModel> Rows { get; set; }
    }

    public class PeriodListViewModelEx
    {
        public PeriodListViewModelEx(IEnumerable<Period> periods)
        {
            CellViewModels = new List<CellViewModel>(periods
                .GroupBy(p => p.LessonNumber)
                .OrderBy(grp => grp.Key)
                .Select(grp =>
                {
                    return new CellViewModel(
                        grp.Select(p => { return Mapper.Map<Period, RowViewModel>(p); }));
                }));
        }
        public List<CellViewModel> CellViewModels { get; set; }
    }

    class DateTimeToDateNameResolver : ValueResolver<DateTime, string>
    {
        protected override string ResolveCore(DateTime source)
        {
            return source.ToShortDateString();
        }
    }

    class DateTimeToDayOfWeekResolver : ValueResolver<DateTime, int>
    {
        protected override int ResolveCore(DateTime source)
        {
            return (int)source.DayOfWeek;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Mapper.CreateMap<Period, RowViewModel>()
                .ForMember(dest => dest.DayName, opt => opt.ResolveUsing<DateTimeToDateNameResolver>().FromMember(src => src.LessonDate))
                .ForMember(dest => dest.DayIndex, opt => opt.ResolveUsing<DateTimeToDayOfWeekResolver>().FromMember(src => src.LessonDate));

            Period[] periods = new Period[3];

            periods[0] = new Period { PeriodId = 1, LessonDate = DateTime.Today.Add(new TimeSpan(1, 0, 0, 0)), LessonNumber = 101, SchoolclassCode = "CS101", Content = "Intro to CS", SchoolyearId = 2013 };
            periods[1] = new Period { PeriodId = 2, LessonDate = DateTime.Today.Add(new TimeSpan(2, 0, 0, 0)), LessonNumber = 101, SchoolclassCode = "CS101", Content = "Intro to CS", SchoolyearId = 2013 };
            periods[2] = new Period { PeriodId = 3, LessonDate = DateTime.Today.Add(new TimeSpan(1, 0, 0, 0)), LessonNumber = 102, SchoolclassCode = "EN101", Content = "English (I)", SchoolyearId = 2013 };

            PeriodListViewModelEx pvModel = new PeriodListViewModelEx(periods);

            Console.WriteLine("CellViews: {0}", pvModel.CellViewModels.Count);

            foreach (CellViewModel cvm in pvModel.CellViewModels)
            {
                Console.WriteLine("{0} items in CellViewModel Group", cvm.Rows.Count);
            }

            Console.WriteLine("Inspecting CellViewModel Rows");
            foreach (CellViewModel cvm in pvModel.CellViewModels)
            {
                foreach (RowViewModel rvm in cvm.Rows)
                {
                    Console.WriteLine("  DayName: {0}", rvm.DayName);
                    Console.WriteLine("  SchoolclassCode: {0}", rvm.SchoolclassCode);
                    Console.WriteLine("  Content: {0}", rvm.Content);
                    Console.WriteLine("  DayIndex: {0}", rvm.DayIndex);
                    Console.WriteLine("  LessonNumber: {0}", rvm.LessonNumber);
                    Console.WriteLine("  -");
                }
                Console.WriteLine("--");
            }

            Console.ReadKey();
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用自动制版机;
命名空间分组映射
{
公共类请求
{
公共IEnumerable句点{get;set;}
公共IEnumerable Weeks{get;set;}
}
公共类RowViewModel
{
公共字符串DayName{get;set;}
公共字符串类代码{get;set;}
公共字符串内容{get;set;}
public int DayIndex{get;set;}
public int LessonNumber{get;set;}
}
公课期间
{
公共整型周期ID{get;set;}
public DateTime LessonDate{get;set;}
public int LessonNumber{get;set;}
公共字符串类代码{get;set;}
公共字符串内容{get;set;}
public int SchoolyearId{get;set;}
//没有规定学年的定义
//公立学年{get;set;}
}
公共类CellViewModel
{
公共CellViewModel()
{
行=新列表();
}
公共单元视图模型(IEnumerable rowVMSet)
{
行=新列表(rowVMSet);
}
公共列表行{get;set;}
}
公共类PeriodListViewModelEx
{
公共时段列表视图模型(IEnumerable periods)
{
CellViewModels=新列表(句点)
.GroupBy(p=>p.LessonNumber)
.OrderBy(grp=>grp.Key)
.选择(grp=>
{
返回新的CellViewModel(
grp.Select(p=>{返回映射器
...
foreach (var groupedPeriod in groupedPeriods)
{
    var cellViewModel = new CellViewModel();
    CellViewModels.Add(cellViewModel);
    foreach (var period in groupedPeriod)
    {
        var rowViewModel = Mapper.Map<RowViewModel>(period); 
        cellViewModel.Rows.Add(rowViewModel);    
    }
}
...
...
foreach (var groupedPeriod in groupedPeriods)
{
    var cellViewModel = new CellViewModel();
    CellViewModels.Add(cellViewModel);
    cellViewModel.Rows = Mapper.Map<List<RowViewModel>>(groupedPeriod);
}
...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using AutoMapper;

namespace GroupingMapping
{
    public class PeriodRequest
    {
        public IEnumerable<Period> Periods { get; set; }
        public IEnumerable<DateTime> Weeks { get; set; }
    }

    public class RowViewModel
    {
        public string DayName { get; set; }
        public string SchoolclassCode { get; set; }
        public string Content { get; set; }
        public int DayIndex { get; set; }
        public int LessonNumber { get; set; }
    }

    public class Period
    {
        public int PeriodId { get; set; }
        public DateTime LessonDate { get; set; }
        public int LessonNumber { get; set; }
        public string SchoolclassCode { get; set; }
        public string Content { get; set; }
        public int SchoolyearId { get; set; }
        // No definition provided for Schoolyear
        //public Schoolyear Schoolyear { get; set; }
    }

    public class CellViewModel
    {
        public CellViewModel()
        {
            Rows = new List<RowViewModel>();
        }

        public CellViewModel(IEnumerable<RowViewModel> rowVMSet)
        {
            Rows = new List<RowViewModel>(rowVMSet);
        }

        public List<RowViewModel> Rows { get; set; }
    }

    public class PeriodListViewModelEx
    {
        public PeriodListViewModelEx(IEnumerable<Period> periods)
        {
            CellViewModels = new List<CellViewModel>(periods
                .GroupBy(p => p.LessonNumber)
                .OrderBy(grp => grp.Key)
                .Select(grp =>
                {
                    return new CellViewModel(
                        grp.Select(p => { return Mapper.Map<Period, RowViewModel>(p); }));
                }));
        }
        public List<CellViewModel> CellViewModels { get; set; }
    }

    class DateTimeToDateNameResolver : ValueResolver<DateTime, string>
    {
        protected override string ResolveCore(DateTime source)
        {
            return source.ToShortDateString();
        }
    }

    class DateTimeToDayOfWeekResolver : ValueResolver<DateTime, int>
    {
        protected override int ResolveCore(DateTime source)
        {
            return (int)source.DayOfWeek;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Mapper.CreateMap<Period, RowViewModel>()
                .ForMember(dest => dest.DayName, opt => opt.ResolveUsing<DateTimeToDateNameResolver>().FromMember(src => src.LessonDate))
                .ForMember(dest => dest.DayIndex, opt => opt.ResolveUsing<DateTimeToDayOfWeekResolver>().FromMember(src => src.LessonDate));

            Period[] periods = new Period[3];

            periods[0] = new Period { PeriodId = 1, LessonDate = DateTime.Today.Add(new TimeSpan(1, 0, 0, 0)), LessonNumber = 101, SchoolclassCode = "CS101", Content = "Intro to CS", SchoolyearId = 2013 };
            periods[1] = new Period { PeriodId = 2, LessonDate = DateTime.Today.Add(new TimeSpan(2, 0, 0, 0)), LessonNumber = 101, SchoolclassCode = "CS101", Content = "Intro to CS", SchoolyearId = 2013 };
            periods[2] = new Period { PeriodId = 3, LessonDate = DateTime.Today.Add(new TimeSpan(1, 0, 0, 0)), LessonNumber = 102, SchoolclassCode = "EN101", Content = "English (I)", SchoolyearId = 2013 };

            PeriodListViewModelEx pvModel = new PeriodListViewModelEx(periods);

            Console.WriteLine("CellViews: {0}", pvModel.CellViewModels.Count);

            foreach (CellViewModel cvm in pvModel.CellViewModels)
            {
                Console.WriteLine("{0} items in CellViewModel Group", cvm.Rows.Count);
            }

            Console.WriteLine("Inspecting CellViewModel Rows");
            foreach (CellViewModel cvm in pvModel.CellViewModels)
            {
                foreach (RowViewModel rvm in cvm.Rows)
                {
                    Console.WriteLine("  DayName: {0}", rvm.DayName);
                    Console.WriteLine("  SchoolclassCode: {0}", rvm.SchoolclassCode);
                    Console.WriteLine("  Content: {0}", rvm.Content);
                    Console.WriteLine("  DayIndex: {0}", rvm.DayIndex);
                    Console.WriteLine("  LessonNumber: {0}", rvm.LessonNumber);
                    Console.WriteLine("  -");
                }
                Console.WriteLine("--");
            }

            Console.ReadKey();
        }
    }
}