3

我有一个非常具体的用例。我有使用 EF6.1.3 生成的实体

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated from a template.
//
//     Manual changes to this file may cause unexpected behavior in your application.
//     Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace MyProject.Data
{
    using System;
    using System.Collections.Generic;

    public partial class Market
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public Market()
        {
            this.Company = new HashSet<Company>();
            this.Partner = new HashSet<Partner>();
            this.Activity = new HashSet<Activity>();
            this.Product = new HashSet<Product>();
        }

        public int market_id { get; set; }
        public string market_name { get; set; }
        public int display_color { get; set; }
        public bool is_modifiable { get; set; }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<Company> Company { get; set; }
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<Partner> Partner { get; set; }
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<Activity> Activity { get; set; }
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<Product> Product { get; set; }
    }
}

我还有一个存储库类,它读取生成的实体类型。在下一层(服务)中,我使用存储库和 AutoMapper 将实体映射到所需的类型。例如,我在 MarketServices 类中有一个 read 方法

public ModelType Read<ModelType>(Expression<Func<Market, bool>> predicate)
{
    var entity = Read(predicate);
    var market = entityMapper.Map<ModelType>(entity);
    return market;
}

使用适当的映射配置,这可以完美地工作。现在,在另一项服务中,我需要使用 MarketServices(多对多关系),因为我想将新公司添加到现有市场的子集。事情从这里开始变得激烈,没有隐藏的细节,我将展示一切:CompanyServices.Create:

public void CreateAndSave(CreateCompanyViewModel viewModel)
{
    var entity = entityMapper.Map<Company>(viewModel);
    if (viewModel.SelectedOperations != null)
    {
        foreach (var marketID in viewModel.SelectedOperations)
        {
            var marketModel = marketsProvider.Read<Market>(m => m.market_id == marketID);
            entity.Market.Add(marketModel);
        }
    }

    Create(entity);
}

错误出现在marketsProvider.Read 行。是的,那将是源类型和目标类型完全相同。如果我选择使用我定义的不同映射,其他一切都有效。我这样定义这个映射:

config.CreateMap<Market, Market>();

所以存储库返回了适当的市场实体,但是当我尝试使用 AutoMapper “传递”它们时,我得到了我见过的最奇怪的(如果我理解你为什么要这样做,我会被诅咒)异常:

映射类型:Market_C126EFB65DDE81A0F02B0BF191A2C8B857DA7226E54AB43FB5DF74D3D3A406ED -> ICollection 1 System.Data.Entity.DynamicProxies.Market_C126EFB65DDE81A0F02B0BF191A2C8B857DA7226E54AB43FB5DF74D3D3A406ED -> System.Collections.Generic.ICollection1[[MyProject.Data.Activity, MyProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]

目标路径:Market.Activity.Activity

源值:System.Data.Entity.DynamicProxies.Market_C126EFB65DDE81A0F02B0BF191A2C8B857DA7226E54AB43FB5DF74D3D3A406ED

那么这里到底发生了什么?如果映射的源类型和目标类型相同,为什么 Automapper 不返回原始对象?有没有办法实现这种行为?

谢谢!

我最终使用了找到的部分解决方案我可以让 AutoMapper 有时返回相同的对象吗?我改变了我的阅读功能,如下所示:

public ModelType Read<ModelType>(Expression<Func<Market, bool>> predicate) where ModelType: class
{
    var entity = Read(predicate);
    if (entity is ModelType)
    {
        return entity as ModelType;
    }

    return entityMapper.Map<ModelType>(entity);
}

我只是将其留在这里,以防其他人偶然发现相同的用例。

4

0 回答 0