C# 将一个递归列表复制到另一个递归列表

C# 将一个递归列表复制到另一个递归列表,c#,entity-framework-core,C#,Entity Framework Core,我正在使用EF core使用以下模型从数据库中获取CategoryMaster表: public class DtoCategoryMaster { public int id { get; set; } [Required] public int parent_category_id { get; set; } [Required] [MaxLength(250)] public string category_type { get; se

我正在使用EF core使用以下模型从数据库中获取
CategoryMaster
表:

public class DtoCategoryMaster 
{
    public int id { get; set; }

    [Required]
    public int parent_category_id { get; set; }

    [Required]
    [MaxLength(250)]
    public string category_type { get; set; }

    [Required]
    [MaxLength(250)]
    public string category_name { get; set; }

    [Required]
    public int display_order { get; set; }
    
    public DateTime date_created {get; set;}
    
    public DateTime date_modified {get; set;}
    
    [ForeignKey("parent_category_id")]
    public virtual DtoCategoryMaster Parent { get; set; }

    public virtual ICollection<DtoCategoryMaster> Children { get; set; }
}
我尝试了很多方法(比如尝试使用automapper,尝试使用linq的映射机制等)来做同样的事情,但在将
CategoryMasterViewModel的子对象映射到
DtoCategoryMaster的对象时遇到了问题

这里我的主要目标是,我只想从API返回所需的属性,这里不需要
date\u created
date\u modified
。这就是为什么创建了不包含此类属性的新ViewModel

基本上,我需要
DtoCategoryMaster
CategoryMasterViewModel
之间正确的映射逻辑


请不要建议将[JsonIgore]或[XmlIgore]放入其他方法。

将工厂方法添加到您的
GetCategoryMasterViewModel
中如何:

public class GetCategoryMasterViewModel 
{
    //...

    public static GetCategoryMasterViewModel From(DtoCategoryMaster dto)
    {
        return new GetCategoryMasterViewModel
        {
            id = dto.id,
            category_name = dto.category_name,
            display_order = dto.display_order,
            Children = dto.Children?.Select(From).ToList()
        };
    }
}
然后您可以这样使用:

var model = GetCategoryMasterViewModel.From(dto);
您甚至可以定义隐式转换:

public class GetCategoryMasterViewModel 
{
    //...

   public static implicit operator GetCategoryMasterViewModel(DtoCategoryMaster dto)
       => From(dto);
}
然后你可以这样做:

GetCategoryMasterViewModel model = dto;

有多种方法可以解决您的问题。您可以编写自己的方法来映射两个对象,或者使用
AutoMapper
nuget库。我更喜欢
AutoMapper

您可以使用下面的代码映射具有内部集合的对象

public void MapTheCollection()
{
     var lst = new List<DtoCategoryMaster>();
     for (int i = 0; i < 5; i++)
     {
         lst.Add(new DtoCategoryMaster() { id = i, category_name = $"{i} Name", display_order = i, Children =  new List<DtoCategoryMaster>()
                {
                     new DtoCategoryMaster(){ id = i},
                     new DtoCategoryMaster() {id = i + 1}
         }});
     }



     var configuration = new MapperConfiguration(cf =>
     {
          cf.CreateMap<DtoCategoryMaster, GetCategoryMasterViewModel>()
                    .ForMember(dest => dest.id, opt => opt.MapFrom(src => src.id))
                    .ForMember(dest => dest.category_name, opt => opt.MapFrom(src => src.category_name))
                    .ForMember(dest => dest.display_order, opt => opt.MapFrom(src => src.display_order));
    });

    var mapper = new Mapper(configuration);
    var output = mapper.Map<List<DtoCategoryMaster>, List<GetCategoryMasterViewModel>>(lst);
}
public void映射集合()
{
var lst=新列表();
对于(int i=0;i<5;i++)
{
添加(新DtoCategoryMaster(){id=i,category_name=$“{i}name”,显示顺序=i,子项=new List()
{
新的DtoCategoryMaster(){id=i},
新的DtoCategoryMaster(){id=i+1}
}});
}
var配置=新的MapperConfiguration(cf=>
{
参见CreateMap()
.ForMember(dest=>dest.id,opt=>opt.MapFrom(src=>src.id))
.FormMember(dest=>dest.category\u name,opt=>opt.MapFrom(src=>src.category\u name))
.ForMember(dest=>dest.display_-order,opt=>opt.MapFrom(src=>src.display_-order));
});
var映射器=新映射器(配置);
var输出=mapper.Map(lst);
}

您不需要使用
ForMember
映射源字段和目标字段,因为您的案例中的两个字段名称相同。我已经包括了这一点,以防将来需要映射不同的属性。

谢谢@Vimal格式化我的问题。你能发布映射逻辑代码吗?我正需要它。这是我不知道的事情:(id和category\u name映射自哪里?
DtoCategoryMaster
@JohnathanBarclay中没有声明它们,我补充道:)谢谢@Jonathan,这是完美的解决方案
public void MapTheCollection()
{
     var lst = new List<DtoCategoryMaster>();
     for (int i = 0; i < 5; i++)
     {
         lst.Add(new DtoCategoryMaster() { id = i, category_name = $"{i} Name", display_order = i, Children =  new List<DtoCategoryMaster>()
                {
                     new DtoCategoryMaster(){ id = i},
                     new DtoCategoryMaster() {id = i + 1}
         }});
     }



     var configuration = new MapperConfiguration(cf =>
     {
          cf.CreateMap<DtoCategoryMaster, GetCategoryMasterViewModel>()
                    .ForMember(dest => dest.id, opt => opt.MapFrom(src => src.id))
                    .ForMember(dest => dest.category_name, opt => opt.MapFrom(src => src.category_name))
                    .ForMember(dest => dest.display_order, opt => opt.MapFrom(src => src.display_order));
    });

    var mapper = new Mapper(configuration);
    var output = mapper.Map<List<DtoCategoryMaster>, List<GetCategoryMasterViewModel>>(lst);
}