在运行时告诉automapper忽略映射,这是否可能?

7

我将使用Entity Framework 6和Automapper来映射实体到DTO。

以下是我的数据模型:

public class PersonDto
{
    public int Id { get; set; }
    public string Name { get; set; }
    public AddressDto Address { get; set; }
}

public class AddressDto
{
    public int Id { get; set; }
    public string Street { get; set; }
    public string City { get; set; }
}

我使用 AutoMapper Queryable Extension 来将数据传输对象 (DTO) 从实体中映射出来。

var personDto = dbContext.People.Project().To<PersonDto>();

上述方法的问题在于它会使EF始终加载地址实体。 我希望只有在明确告诉它们要包含(x => x.Address)时,才会加载地址。 如果我在automapper映射中指定ignore(),则地址将不会被加载。 是否有可能在运行时告诉automapper忽略地址属性? 我正在使用的Automapper查询扩展程序不支持所有功能,如“条件或映射后”。 是否有任何解决方法?

1
为什么不创建一个没有地址的不同PersonDto呢? - scottheckel
那些是简化模型。我的真实模型可能有超过3个类似的属性。为每种情况创建单独的模型会很麻烦。 - Reynaldi
@Reynaldi,看起来Queryable扩展会自动为您加载实体。我不确定这是如何工作的,但您可以尝试关闭延迟加载,设置包含内容,然后调用Project()方法。 - DDiVita
1个回答

7

您需要为DTO启用显式扩展。首先在您的配置中:

Mapper.CreateMap<Person, PersonDto>()
    .ForMember(d => d.Address, opt => opt.ExplicitExpansion());

然后在运行时:

dbContext.People.Project.To<PersonDto>(membersToExpand: d => d.Address);

"membersToExpand" 可以是一个表达式列表,用于表示目标成员,也可以是一个字符串值字典,用于表示要展开的属性名称。

但是我能否仍然使用mapper.map进行普通映射呢? - Reynaldi
你的问题中提到了投影 - 在AutoMapper中这两个特性是不能互换的。 - Jimmy Bogard
1
如果我有多个成员需要扩展,该怎么办?我不能这样做:membersToExpand: d => new {d.Address, d.Address2}。并且是否可以扩展子实体,例如:membersToExpand: d => d.Address.Select(x => x.Country)? - Reynaldi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接