如何有条件地映射我的属性,值也是有条件的。 以下是我的代码详情: -
public class Team
{
public string Id { get; set; }
public Driver Driver { get; set; }
public Driver Codriver { get; set; }
}
public class Driver
{
public string DriverId { get; set; }
public List<Score> Scores { get; set; }
}
public class Score
{
public string Id { get; set; }
public string Name { get; set; }
public string Type { get; set; }
public string Value { get; set; }
public int Score1 { get; set; }
public int Score2 { get; set; }
}
我想移动司机和codriver。如果我想更新我的驱动程序,则Score1将更新,否则为Score2。如果我想用Driver更新它,那么Score1的细节将被移动,否则为Score2。我的映射如下: -
public void Move(Score sourceScore, string sourceType, Score targetScore, string targetType)
{
Mapper.Initialize(cfg =>
{
cfg.CreateMap<Score, Score>()
.ForMember(dest => dest.Score1, opt =>
{
opt.Condition((System.Func<Score, bool>) (src => string.Equals(targetType, "Driver")));
opt.MapFrom(src => string.Equals(sourceType, "Driver") ? src.Score1 : src.Score2);
})
.ForMember(dest => dest.Score2, opt =>
{
opt.Condition((System.Func<Score, bool>) (src => string.Equals(targetType, "CoDriver")));
opt.MapFrom(src => string.Equals(sourceType, "Driver") ? src.Score1 : src.Score2);
});
});
Mapper.Map<Score, Score>(sourceScore, targetScore);
}
上面完成的映射并没有正确映射细节。我错过了什么。有人可以帮我这个。
答案 0 :(得分:0)
您必须检查您的逻辑并准确解释您想要获得的内容。目前您的代码执行此操作:
targetType
为"Driver"
而sourceType
为"Driver"
:目标中的Score1会获得来自Score1的值。targetType
为"Driver"
且sourceType
除"Driver"
以外的任何内容:目标中的Score1将获得来自Score2的值。targetType
为"CoDriver"
且sourceType
为"Driver"
,则目标中的得分2将获得来自Score1的值。targetType
为"CoDriver"
且sourceType
除"Driver"
以外的任何内容:目标中的Score2将获得来自Score2的值。如果这不是您想要的,请修改此规则,以便说明它。请注意,当您提出类似这样的问题时,您应该明确指出哪些内容没有按预期工作,并且理想情况下提供一个工作示例和一些指定所需行为的单元测试。像这样:
internal static class MappingDrivers
{
public static void Move(Score sourceScore, string sourceType, Score targetScore, string targetType)
{
Mapper.Initialize(cfg =>
{
cfg.CreateMap<Score, Score>()
.ForMember(dest => dest.Score1, opt =>
{
opt.Condition(src => string.Equals(targetType, "Driver"));
opt.MapFrom(src => string.Equals(sourceType, "Driver") ? src.Score1 : src.Score2);
})
.ForMember(dest => dest.Score2, opt =>
{
opt.Condition(src => string.Equals(targetType, "CoDriver"));
opt.MapFrom(src => string.Equals(sourceType, "Driver") ? src.Score1 : src.Score2);
});
});
Mapper.Map(sourceScore, targetScore);
}
}
注意:我没有使用TestCase来保持简单
internal class TestMappingDrivers
{
[Test]
public void WhenTargetIsDriverAndSourceIsDriver_Score1GetsValueFromScore1()
{
int score1 = 666;
var source = new Score
{
Score1 = score1,
Score2 = 667
};
var destination = new Score();
MappingDrivers.Move(source, "Driver", destination, "Driver");
Assert.AreEqual(score1, destination.Score2); // Intentionally failing, it should be Assert.AreEqual(score1, destination.Score1);
}
[Test]
public void WhenTargetIsDriverAndSourceIsSomethingElse_Score1GetsValueFromScore2()
{
int score2 = 667;
var source = new Score
{
Score1 = 666,
Score2 = score2
};
var destination = new Score();
MappingDrivers.Move(source, "SomethingElse", destination, "Driver");
Assert.AreEqual(score2, destination.Score1); // Passing
}
[Test]
public void WhenTargetIsCoDriverAndSourceIsDriver_Score1GetsValueFromScore1()
{
int score1 = 666;
var source = new Score
{
Score1 = score1,
Score2 = 667
};
var destination = new Score();
MappingDrivers.Move(source, "Driver", destination, "CoDriver");
Assert.AreEqual(score1, destination.Score2); // Passing
}
[Test]
public void WhenTargetIsCoDriverAndSourceIsSomethingElse_Score1GetsValueFromScore2()
{
int score2 = 667;
var source = new Score
{
Score1 = 666,
Score2 = score2
};
var destination = new Score();
MappingDrivers.Move(source, "SomethingElse", destination, "CoDriver");
Assert.AreEqual(score2, destination.Score2); // Passing
}
}
另请注意,您应该只在应用程序启动期间初始化映射一次。每次调用Move
函数时,您都在执行此操作。查看the docs。
最后,我会说你正在使用错误的工具来完成这项工作。 AutoMapper通常用于在两个不同的类之间进行映射,而不是从一个类的实例到同一个类的其他实例。你可以做到,但它“很奇怪”。我认为,对于你想要做的事情,正常的条件表达式(如果......其他)会更清楚地表达你的意图并且不易出错。