我有一个非常具体的用例。我有使用 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.ICollection
1[[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);
}
我只是将其留在这里,以防其他人偶然发现相同的用例。