C# 如何使AutoMapper不缓存映射对象?
当AutoMapper遇到已经映射的对象时,它似乎会再次使用该对象,而不是尝试重新映射它。我相信它是基于C# 如何使AutoMapper不缓存映射对象?,c#,.net,automapper,C#,.net,Automapper,当AutoMapper遇到已经映射的对象时,它似乎会再次使用该对象,而不是尝试重新映射它。我相信它是基于.Equals()实现的 我有一棵正在绘制的树。因此,一个具有一些属性和子节点的节点。多个节点具有相同的值.Equals(),因为它基于Id属性。节点的子节点不同,我需要重新映射这些子节点,但它使用缓存的映射值 有没有办法关闭缓存映射?我所能想到的就是实现一个新的转换器,但这完全违背了使用AutoMapper的目的 下面是一个关于如何复制的示例 void Main() { var so
.Equals()
实现的
我有一棵正在绘制的树。因此,一个具有一些属性和子节点的节点。多个节点具有相同的值.Equals()
,因为它基于Id属性。节点的子节点不同,我需要重新映射这些子节点,但它使用缓存的映射值
有没有办法关闭缓存映射?我所能想到的就是实现一个新的转换器,但这完全违背了使用AutoMapper的目的
下面是一个关于如何复制的示例
void Main()
{
var source = new List<Tag>
{
new Tag
{
Id = 1,
Name = "Tag 1",
ChildTags = new List<Tag>
{
new Tag
{
Id = 2,
Name = "Tag 2",
ChildTags = new List<Tag>
{
new Tag {Id = 3, Name = "Tag 3"},
new Tag {Id = 4, Name = "Tag 4"}
}
}
}
},
new Tag { Id = 1, Name = "Tag 1" },
new Tag
{
Id = 3, Name = "Tag 3", ChildTags = new List<Tag>
{
new Tag {Id = 4, Name = "Tag 4"}
}
}
};
Mapper.CreateMap<Tag, Tag>();
var results = Mapper.Map<IList<Tag>, IList<Tag>>(source);
results.Dump();
}
public class Tag
{
public int Id { get; set; }
public string Name { get; set; }
public IEnumerable<Tag> ChildTags { get; set; }
public override bool Equals(Object obj)
{
if (obj == null)
{
return false;
}
var x = this;
var y = (Tag)obj;
return x.Id.Equals(y.Id);
}
public override int GetHashCode()
{
return Id.GetHashCode();
}
}
void Main()
{
var source=新列表
{
新标签
{
Id=1,
Name=“Tag 1”,
ChildTags=新列表
{
新标签
{
Id=2,
Name=“tag2”,
ChildTags=新列表
{
新标记{Id=3,Name=“Tag 3”},
新标记{Id=4,Name=“Tag 4”}
}
}
}
},
新标记{Id=1,Name=“Tag 1”},
新标签
{
Id=3,Name=“Tag 3”,ChildTags=新列表
{
新标记{Id=4,Name=“Tag 4”}
}
}
};
CreateMap();
var results=Mapper.Map(源);
结果:Dump();
}
公共类标签
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共IEnumerable子标签{get;set;}
公共覆盖布尔等于(对象对象对象)
{
if(obj==null)
{
返回false;
}
var x=这个;
变量y=(标记)obj;
返回x.Id等于(y.Id);
}
公共覆盖int GetHashCode()
{
返回Id.GetHashCode();
}
}
当AutoMapper遇到已映射的对象时,它将
似乎再次使用该对象,而不是尝试重新映射它。我
相信它是基于.Equals()实现的
你能解释一下为什么以及什么时候你会看到吗
在快速查看源代码之后,我确定没有对象的缓存。
下面是一个测试,说明了这一点:
public class CustomerSource
{
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateOfBirth { get; set; }
public int NumberOfOrders { get; set; }
}
public class CustomerTarget
{
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateOfBirth { get; set; }
public int NumberOfOrders { get; set; }
}
[TestMethod]
public void Test_AutoMapper()
{
Mapper.CreateMap<CustomerSource, CustomerTarget>();
var source = new CustomerSource() { DateOfBirth = DateTime.Now, FirstName = "FirstName", LastName = "LastName", NumberOfOrders = int.MaxValue };
var res1 = Mapper.Map<CustomerSource, CustomerTarget>(source);
Console.WriteLine(res1.FirstName); // PRINT FirstName
source.FirstName += "[UPDATED]";
source.LastName += "[UPDATED]";
var res2 = Mapper.Map<CustomerSource, CustomerTarget>(source);
Console.WriteLine(res1.FirstName); // PRINT FirstName[UPDATED]
}
公共类CustomerSource
{
公共字符串名{get;set;}
公共字符串LastName{get;set;}
公共日期时间出生日期{get;set;}
public int NumberOfOrders{get;set;}
}
公共类CustomerTarget
{
公共字符串名{get;set;}
公共字符串LastName{get;set;}
公共日期时间出生日期{get;set;}
public int NumberOfOrders{get;set;}
}
[测试方法]
公共无效测试_AutoMapper()
{
CreateMap();
var source=new CustomerSource(){DateOfBirth=DateTime.Now,FirstName=“FirstName”,LastName=“LastName”,NumberOfOrders=int.MaxValue};
var res1=Mapper.Map(源);
Console.WriteLine(res1.FirstName);//打印FirstName
source.FirstName+=“[更新]”;
source.LastName+=“[更新]”;
var res2=Mapper.Map(源);
Console.WriteLine(res1.FirstName);//打印FirstName[更新]
}
没有您的代码,很难进行更深入的研究。
还有一个方法Mapper.Reset()用于清除MapperEngine和MapingConfiguration(所有内部映射表达式都将丢失)我也遇到了同样的问题。 当您两次映射同一对象时不会发生这种情况-当您有一个对象的树继承者时会发生这种情况,并且相同的值存在于树的两个位置(但具有不同的子值) 映射项的第二个实例时,它使用第一个实例的子值,而不是重新评估子值应该是什么 以下是我的例子:
class Tag {
int Id {get; set;}
string Name {get; set;}
IEnumerable<Tag> ChildTags {get; set;}
}
public void Test()
{
var source = new List<Tag>
{
new Tag { Id = 1, Name = "Tag 1", ChildTags = new List<Tag>
{
new Tag { Id = 2, Name = "Tag 2", ChildTags = new List<Tag>
{
new Tag {Id = 3, Name = "Tag 3"},
new Tag {Id = 4, Name = "Tag 4"}
}
}
}
},
new Tag { Id = 1, Name = "Tag 1" },
new Tag {
Id = 3, Name = "Tag 3", ChildTags = new List<Tag>
{
new Tag {Id = 4, Name = "Tag 4"}
}
}
};
Mapper.CreateMap<Tag, Tag>()
.ForMember(dest => dest.ChildTags,
opt => opt.MapFrom(src => src.ChildTags));
var result = Mapper.Map<IList<Tag>, IList<Tag>>(tags);
}
类标记{
int Id{get;set;}
字符串名称{get;set;}
IEnumerable ChildTags{get;set;}
}
公开无效测试()
{
var source=新列表
{
新标签{Id=1,Name=“Tag 1”,ChildTags=new List
{
新标签{Id=2,Name=“Tag 2”,ChildTags=new List
{
新标记{Id=3,Name=“Tag 3”},
新标记{Id=4,Name=“Tag 4”}
}
}
}
},
新标记{Id=1,Name=“Tag 1”},
新标签{
Id=3,Name=“Tag 3”,ChildTags=新列表
{
新标记{Id=4,Name=“Tag 4”}
}
}
};
Mapper.CreateMap()
.ForMember(dest=>dest.ChildTags,
opt=>opt.MapFrom(src=>src.ChildTags));
var result=Mapper.Map(标记);
}
结果
- 标记1(即源代码[0])的第一个实例及其所有子项都是完美的
- 标记1的第二个实例(即源代码[1])包含第一个实例的所有子项—它不应该包含任何子项
- 标记3的第二个实例(即源代码[2])没有任何子项-它应该将标记4作为子项
Mapper.Reset();
Mapper.CreateMap<Tag, Tag>();
var results = Mapper.Map<IList<Tag>, IList<Tag>>(source, opt => opt.DisableCache = true);