Skip to content

Commit e077521

Browse files
authored
Merge pull request #57 from BlaiseD/master
Adding mapping for member init expressions.
2 parents b3ab5ff + a27af4c commit e077521

File tree

3 files changed

+49
-1
lines changed

3 files changed

+49
-1
lines changed

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<PropertyGroup>
33
<Authors>Jimmy Bogard</Authors>
44
<LangVersion>latest</LangVersion>
5-
<VersionPrefix>3.0.6</VersionPrefix>
5+
<VersionPrefix>3.0.7-preview01</VersionPrefix>
66
<WarningsAsErrors>true</WarningsAsErrors>
77
<NoWarn>$(NoWarn);1701;1702;1591</NoWarn>
88
</PropertyGroup>

src/AutoMapper.Extensions.ExpressionMapping/XpressionMapperVisitor.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,40 @@ protected override Expression VisitLambda<T>(Expression<T> node)
129129
return mapped;
130130
}
131131

132+
protected override Expression VisitMemberInit(MemberInitExpression node)
133+
{
134+
if (this.TypeMappings.TryGetValue(node.Type, out Type newType))
135+
{
136+
var typeMap = ConfigurationProvider.CheckIfMapExists(sourceType: newType, destinationType: node.Type);
137+
//The destination becomes the source because to map a source expression to a destination expression,
138+
//we need the expressions used to create the source from the destination
139+
140+
IEnumerable<MemberBinding> bindings = node.Bindings.Select
141+
(
142+
binding =>
143+
{
144+
Expression bindingExpression = ((MemberAssignment)binding).Expression;
145+
return DoBind
146+
(
147+
typeMap.GetPropertyMapByDestinationProperty(binding.Member.Name),
148+
bindingExpression,
149+
this.Visit(bindingExpression)
150+
);
151+
}
152+
);
153+
154+
return Expression.MemberInit(Expression.New(newType), bindings);
155+
}
156+
157+
return base.VisitMemberInit(node);
158+
}
159+
160+
private MemberBinding DoBind(PropertyMap propertyMap, Expression initial, Expression mapped)
161+
{
162+
this.TypeMappings.AddTypeMapping(ConfigurationProvider, initial.Type, mapped.Type);
163+
return Expression.Bind(propertyMap.SourceMember, mapped);
164+
}
165+
132166
protected override Expression VisitBinary(BinaryExpression node)
133167
{
134168
return DoVisitBinary(this.Visit(node.Left), this.Visit(node.Right), this.Visit(node.Conversion));

tests/AutoMapper.Extensions.ExpressionMapping.UnitTests/XpressionMapperTests.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,20 @@ public void Map__select_method_projecting_to_anonymous_type()
415415
Assert.True(bars.Count == 1);
416416
}
417417

418+
[Fact]
419+
public void Map__select_method_projecting_to_model_type()
420+
{
421+
//Arrange
422+
Expression<Func<UserModel, IEnumerable<ThingModel>>> selection = s => s.AccountModel.ThingModels.Select(x => new ThingModel { Car = x.Car }).Where(b => b.Color.EndsWith("e"));
423+
424+
//Act
425+
Expression<Func<User, IEnumerable<Thing>>> selectionMapped = mapper.MapExpression<Expression<Func<User, IEnumerable<Thing>>>>(selection);
426+
List<Thing> things = Users.SelectMany(selectionMapped).ToList();
427+
428+
//Assert
429+
Assert.True(things.Count == 2);
430+
}
431+
418432
[Fact]
419433
public void Map__select_method_where_parent_type_is_grandchild_type()
420434
{

0 commit comments

Comments
 (0)