我有一个非常具体的用例。我有使用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 - &GT; ICollection的
1 System.Data.Entity.DynamicProxies.Market_C126EFB65DDE81A0F02B0BF191A2C8B857DA7226E54AB43FB5DF74D3D3A406ED -> System.Collections.Generic.ICollection
1 [[MyProject.Data.Activity, MyProject,Version = 1.0.0.0,Culture = neutral, 公钥=空]]目标路径:Market.Activity.Activity
来源价值: System.Data.Entity.DynamicProxies.Market_C126EFB65DDE81A0F02B0BF191A2C8B857DA7226E54AB43FB5DF74D3D3A406ED
那究竟发生了什么?如果映射的源类型和目标类型相同,Automapper为什么不返回原始对象?有没有办法实现这种行为?
谢谢!
我最终使用了部分解决方案Can I get AutoMapper to return the same object sometimes?,我改变了我的读取功能,如下所示:
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);
}
我要留下这个以防万一其他人偶然发现同一个用例。