Automapper 在 Collection 属性中设置 null 而不是在源中

问题描述 投票:0回答:1

我在 ASP.NET Core 6.0 项目中使用 AutoMapper 12.0.0。

当我有这样的收藏时:

public class Item
{
    public int Id { get; set; }
    public string? VideoUrl { get; set; }
    public ICollection<ItemTr> Translations { get; set; }
}

public class ItemTr 
{
    public int ParentId { get; set; }
    public Item Parent { get; set; }
    public string LanguageCode { get; set; }

    public string? Summary { get; set; }
    public string? Report { get; set; }
    public string? Incidences { get; set; }
}

然后我有一个像这样的模型视图:

public class ItemView
{
    public int Id { get; set; }
    public List<ItemTrView> Translations { get; set; }
}

public class ItemTrView
{
    public int ParentId { get; set; }
    public string LanguageCode { get; set; }

    public string? Summary { get; set; }
    public string? Report { get; set; }
}

如您所见,我缺少模型视图中的 Incidences 字段,我不需要它。

我创建了这样的 AUtomapper:

    CreateMap<Item, ItemView>(MemberList.Source).ReverseMap();
    CreateMap<ItemTr, ItemTrView>(MemberList.Source).ReverseMap();

阅读时,我能够将所有属性从 Item 传递到我的模型视图 ItemView 并使用它们。

问题是当我尝试保存更改时。

[HttpPost]
public IActionResult ReportsModalDo(ItemView model)
{
    var item = _unitOfWork.Item.Get(item);
    _mapper.Map(model, item);
    
    _unitOfWork.Complete();
}

它不会更改任何 Item 属性,因为这些属性不存在于 SOURCE(即 ItemView)中,并且它确实将更改保存在 Translations Collection 中,因此 Summary 和 Report 已正确更改,但 Incidences 设置为 null。

我想要的是 Incidences 保持原样,因为源 ItemTrView 中没有 Incidences 属性。

我也尝试过添加一个

.ForMember(x => x.Incidences, o => o.Ignore())

但它什么也没做。

有什么想法吗?我在这里错过了什么吗?

谢谢。

asp.net asp.net-core automapper asp.net-core-6.0
1个回答
0
投票

我想要的是事件发生率保持原样,因为没有 源 ItemTrView 中的 Incidences 属性。任何想法?我失踪了吗 这里有什么吗?

嗯,根据您的场景、描述和共享代码片段,AutoMappe 似乎正在用 null 覆盖

Incidences
属性,因为它不存在于源中
ItemTrViewAutoMapper

您可能知道,AutoMapper 使用特定的顺序来映射属性。由于您在忽略 Incidences 属性之前已经定义了

Item
ItemTr
的映射,因此稍后它可能会覆盖该配置。

为了解决这个问题,您可以在 Item 和 ItemTr 的映射之后移动

.ForMember(x => x.Incidences, o => o.Ignore())
配置。所以你可以这样做:

CreateMap<ItemTr, ItemTrView>(MemberList.Source)
    .ForMember(x => x.Incidences, o => o.Ignore());

CreateMap<Item, ItemView>(MemberList.Source);

或者,您可以使用

ForAllMembers
选项忽略任何嵌套集合中的 Incidences 属性。在这种情况下,您可以重构如下:

CreateMap<ItemTr, ItemTrView>(MemberList.Source)
    .ForMember(x => x.Incidences, o => o.Ignore());

CreateMap<Item, ItemView>(MemberList.Source)
    .ForAllMembers(opts => opts.Condition((src, dest, member) => member.Name != "Incidences"));

我希望上述修改能够解决您的问题。

© www.soinside.com 2019 - 2024. All rights reserved.