我正在尝试使用AutoMapper的嵌套映射,使用映射器的实例版本 - 但它似乎不起作用。
这是我正在使用的两个模型:
public class User
{
[Key]
public string Email { get; set; }
public string Hash { get; set; }
public string Salt { get; set; }
public string Name { get; set; }
public virtual ICollection<TaskTime> TaskTimes { get; set; }
public virtual ICollection<Role> Roles { get; set; }
public virtual ICollection<HistoricalEstimation> HistoricalEstimations { get; set; }
}
public class TaskTime
{
public int Id { get; set; }
public User User { get; set; }
public Task Task { get; set; }
public TimeSpan Duration { get; set; }
public DateTime Date { get; set; }
}
我正在使用此代码映射它们:
public static class UserViewConfiguration
{
private static ConfigurationStore configuration;
public static MappingEngine Engine { get; private set; }
static UserViewConfiguration()
{
configuration = new ConfigurationStore(new TypeMapFactory(), MapperRegistry.AllMappers());
Engine = new MappingEngine(configuration);
configuration.CreateMap<User, UserFull>();
configuration.CreateMap<TaskTime, UserTaskTime>();
/* snip... */
configuration.AssertConfigurationIsValid();
}
}
到这些视图模型上:
public class UserFull
{
public string Email { get; set; }
public string Name { get; set; }
public virtual ICollection<TaskTime> TaskTimes { get; set; }
}
public class UserTaskTime
{
public int Id { get; set; }
public Task Task { get; set; }
public TimeSpan Duration { get; set; }
public DateTime Date { get; set; }
}
问题是,User
包含TaskTime
,而TaskTime
包含User
。这个循环需要存在,因为有几种不同的方式来获取每个项目,具体取决于您最初要求的对象(这就是我使用AutoMapper的实例版本的原因)。我正在序列化它们以通过ASP.NET MVC API应用程序发送它们,因此循环是一个大问题。
我已经阅读了this example of using nested mappings with AutoMapper,从我能说的我做得对。但是对于上面的映射,我在路径User
[0].TaskTimes[0].User.TaskTimes
上遇到了自引用循环错误。如果我注释掉TaskTimes
的{{1}}属性,我就不会收到错误,因此我知道UserFull
映射正在运行 - 但出于某种原因User->UserFull
没有用。
我该怎么办?
编辑:我这样映射:
TaskTime->UserTaskTime
答案 0 :(得分:3)
假设你有一个拼写错误,并且UserFull应该有一个UserTaskTime的集合而不是TaskTime的集合,这些快速测试工作:
[TestFixture]
public class MappingTests2
{
[Test]
public void AutoMapper_Configuration_IsValid()
{
UserViewConfiguration.Configure();
Mapper.AssertConfigurationIsValid();
}
[Test]
public void AutoMapper_MapsAsExpected()
{
UserViewConfiguration.Configure();
Mapper.AssertConfigurationIsValid();
var user = new User
{
Email = "user1@email.com",
Hash = "1234Hash",
Name = "user1",
Salt = "1234Salt",
TaskTimes =
new Collection<TaskTime>
{
new TaskTime
{ Date = new DateTime(2012, 11, 01), Duration = new TimeSpan(0, 20, 1), Id = 1 },
new TaskTime
{ Date = new DateTime(2012, 11, 02), Duration = new TimeSpan(0, 20, 2), Id = 2 }
}
};
foreach (var taskTime in user.TaskTimes)
{
taskTime.User = user;
}
var userView = Mapper.Map<User, UserFull>(user);
Assert.That(userView, Is.Not.Null);
Assert.That(userView.Email, Is.EqualTo("user1@email.com"));
Assert.That(userView.Name, Is.EqualTo("user1"));
Assert.That(userView.TaskTimes, Is.Not.Null);
Assert.That(userView.TaskTimes.Count, Is.EqualTo(2));
var tt = userView.TaskTimes.FirstOrDefault(x => x.Id == 1);
Assert.That(tt, Is.Not.Null);
Assert.That(tt.Id, Is.EqualTo(1));
Assert.That(tt.Date, Is.EqualTo(new DateTime(2012, 11, 01)));
Assert.That(tt.Duration, Is.EqualTo(new TimeSpan(0, 20, 1)));
}
}
请注意,对于上面的内容,我将映射转换回使用静态方法:
public static void Configure()
{
Mapper.CreateMap<User, UserFull>();
Mapper.CreateMap<TaskTime, UserTaskTime>();
Mapper.AssertConfigurationIsValid();
}
如果您确实打算将其作为TaskTime,我会再看看。