是否有通用的方法来连接列表并将特定值瞄准属性?

时间:2016-03-15 22:13:55

标签: c# generics join linq-to-sql

我想找到一种以通用方式重现下面代码的方法。通常在我使用的软件中,我们比较两个对象列表:

 d.FeatureViewModels = (from feature in d.FeatureViewModels
                        join pairedFeature in s.FeaturePairTransit on feature.Id equals pairedFeature.Feature.Id
                        select new FeatureViewModel
                        {
                            Id = feature.Id,
                            Name = feature.Name,
                            DisplayOrder = feature.DisplayOrder,
                            MembershipId = feature.MembershipId,
                            IsPaired = pairedFeature.IsPaired,
                            TranslationId = feature.TranslationId,
                            DisplayNameViewModel = feature.DisplayNameViewModel,
                            DescriptionViewModel = feature.DescriptionViewModel
                        }).ToList();

如您所见,需要添加的字段是IsPaired,其他所有字段都来自功能。这也适用于应用程序中其他地方的许多对象。我不想每次都复制,粘贴和调整上面的代码,而是希望有一个可以重用的通用方法,如果有可能的话。为此目的我需要一些帮助。

任何人都可以提供帮助吗?

大卫

修改

根据Matias的回答和评论,我认为我必须更精确:

FeaturePairTransit类如下所示:

public class FeaturePairTransit
    {
        public Feature Feature { get; set; }
        public bool IsPaired { get; set; }
    }

此外,FeatureViewModel中包含IsPaired属性 我想要实现的是找到一种方法将FeaturePairTransit.IsPaired映射到FeatureViewModel.IsPaired并重用该模式。

这是针对该特定问题的完整AutoMapper代码:

    Mapper.CreateMap<SKUFeatureTransit, SKUFeaturePivotViewModel>()
// Will give a different level error
                    //.ForMember(d => d.FeatureViewModels.Select(x => x.IsPaired), opt => opt.MapFrom(s => s.FeaturePairTransit.Select(x => x.IsPaired)))
                    .AfterMap((s, d) => d.SKUViewModel = Mapper.Map<SKUViewModel>(s.SKU))
                    .AfterMap((s, d) =>
                    {
                        // This is mandatory because we need to instantiate every translation fields with the constructor.
                        d.FeatureViewModels = Mapper.Map<IList<FeatureViewModel>>(s.FeaturePairTransit.Select(x => x.Feature));

                        // We cannot map an individual property (IsPaired) from a different level. So we did this comparaison.
                        d.FeatureViewModels = (from feature in d.FeatureViewModels
                                               join pairedFeature in s.FeaturePairTransit on feature.Id equals pairedFeature.Feature.Id
                                               select new FeatureViewModel
                                               {
                                                   Id = feature.Id,
                                                   Name = feature.Name,
                                                   DisplayOrder = feature.DisplayOrder,
                                                   MembershipId = feature.MembershipId,
                                                   IsPaired = pairedFeature.IsPaired,
                                                   TranslationId = feature.TranslationId,
                                                   DisplayNameViewModel = feature.DisplayNameViewModel,
                                                   DescriptionViewModel = feature.DescriptionViewModel
                                               }).ToList();
                    });

然后,我看到两个选项,也许有一些东西,如@Matias所说,所以AutoMapper可以照顾,我仍然试图弄清楚或我可以通用的方式进行映射。有什么建议吗?

2 个答案:

答案 0 :(得分:0)

AutoMapperAutoMapperAutoMapper ...

您可以将代码转换为:

 d.FeatureViewModels = (from feature in d.FeatureViewModels
                        join pairedFeature in s.FeaturePairTransit on feature.Id equals pairedFeature.Feature.Id
                        select mapper.Map<Feature, FeatureViewModel>(feautre)).ToList();

@devuxer在一些评论中说:

  

是的,但不是那么简单。您还需要一个CreateMap语句。

好的,因为看起来视图模型和域对象具有相同的属性....你需要调用...:

var mapperConfig = new MapperConfiguration(cfg => {
    cfg.CreateMap<Feature, FeatureViewModel>();
});

var mapper = mapperConfig.CreateMapper();

...在致电mapper.Map(...)之前!

答案 1 :(得分:0)

我终于找到了我想要的东西。

这不像我想象的那样通用,但它是朝着正确方向迈出的一大步。

// HTTPGET
            Mapper.CreateMap<SKUFeatureTransit, SKUFeaturePivotViewModel>()
                .AfterMap((s, d) => d.SKUViewModel = Mapper.Map<SKUViewModel>(s.SKU))
                .AfterMap((s, d) =>
                {
                    // This is mandatory because we need to instantiate every translation fields with the constructor.
                    d.FeatureViewModels = Mapper.Map<IList<FeatureViewModel>>(s.FeaturePairTransit.Select(x => x.Feature));

                    // We cannot map an individual property (IsPaired) from a different level. So we did this comparaison.
                    d.FeatureViewModels = d.FeatureViewModels.Join(s.FeaturePairTransit, vModel => vModel.Id, source => source.Feature.Id, (dest, source) =>
                    {
                        dest.IsPaired = source.IsPaired;
                        return dest;
                    }).ToList();
                });

希望这可以帮助别人

大卫