阻止AutoMapper预测强制加载相关数据

RMD*_*RMD 4 entity-framework automapper

有没有办法配置AutoMapper以遵守实体框架的.Include样式加载指令?

我已经为我的上下文禁用了延迟加载,我想有条件地为特定实体加载相关数据.理想情况下,我想通过使用include语法来实现这一点.就像是:

if(loadAddreses)
{
    query = query.Include(e => e.Addresses);
}

if(loadEmails)
{
    query = query.Include(e => e.Emails);
}
Run Code Online (Sandbox Code Playgroud)

问题是,AutoMapper看到我正在预测的模型包括地址和电子邮件,并且正在生成加载所有数据的SQL,无论我要求EF包含什么.换一种说法:

var model = query.Project.To<MyModel>();
Run Code Online (Sandbox Code Playgroud)

如果MyModel具有Addresses集合,它将加载地址,而不管我的Include语句.

如果没有更改我的模型,以便我有一个没有地址或电子邮件属性的模型,有没有办法解决这个问题?我想我可以改变我的映射,但映射通常是静态的,并且在最初创建后不会改变.

nic*_*k_w 6

这有点难以理解,但看看这对你有什么用.请注意,我使用的是AutoMapper的3.3.0-ci1027版本(在撰写本文时,这是一个预发行版).

假设我的数据模型如下所示:

public class Address
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int AddressId { get; set; }
    public string Text { get; set; }
}

public class Email
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int EmailId { get; set; }
    public string Text { get; set; }
}

public class User
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int UserId { get; set; }
    public virtual ICollection<Address> Addresses { get; set; }
    public virtual ICollection<Email> Emails { get; set; }

    public User()
    {
        this.Addresses = new List<Address>();
        this.Emails = new List<Email>();
    }
}
Run Code Online (Sandbox Code Playgroud)

我没有指定我的视图模型,但它们只包含与实体相同的属性.

我从映射User到UserViewModel如下所示:

Mapper.CreateMap<User, UserViewModel>()
    .ForMember(x => x.Emails, opt => opt.ExplicitExpansion())
    .ForMember(x => x.Addresses, opt => opt.ExplicitExpansion());
Run Code Online (Sandbox Code Playgroud)

我的预测看起来像这样:

var viewModels = context.Set<User>().Project()
    .To<UserViewModel>(new { }, u => u.Emails).ToList();
Run Code Online (Sandbox Code Playgroud)

使用该映射和投影,仅Emails加载集合.对此的重要部分是opt => opt.ExplicitExpansion()映射中的调用 - 除非在投影期间显式扩展,否则将阻止导航属性被跟踪,以及重载To方法.这个重载允许你指定参数(我作为一个空对象留下)和你想要扩展的成员(在这种情况下只是Emails).

在这个阶段我不确定的一件事是从Include语句中提取细节的精确机制,这样你就可以将它们传递给To方法,但希望这会给你一些工作.