Skip to content

Commit

Permalink
#54 : Map between IEnumerable<> and ICollection<> or IList<>
Browse files Browse the repository at this point in the history
  • Loading branch information
anisimovyuriy committed Nov 13, 2015
1 parent 46d43aa commit a144e75
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 29 deletions.
39 changes: 19 additions & 20 deletions ExpressMapper NET40/SourceTypeMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,26 +112,25 @@ private void ProcessProjectingMember(Expression sourceExp, PropertyInfo destProp
MappingService.GetMemberQueryableExpression(sourceExp.Type,
destProp.PropertyType);


var tCol =
sourceExp.Type.GetInterfaces()
.FirstOrDefault(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof (IEnumerable<>)) ??
.FirstOrDefault(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IEnumerable<>)) ??
(sourceExp.Type.IsGenericType
&& sourceExp.Type.GetInterfaces().Any(t => t == typeof(IEnumerable))
? sourceExp.Type
: null);

var tnCol = destProp.PropertyType.GetInterfaces()
.FirstOrDefault(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof (IEnumerable<>)) ??
.FirstOrDefault(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IEnumerable<>)) ??
(destProp.PropertyType.IsGenericType &&
destProp.PropertyType.GetInterfaces().Any(t => t == typeof (IEnumerable))
destProp.PropertyType.GetInterfaces().Any(t => t == typeof(IEnumerable))
? destProp.PropertyType
: null);

if (sourceExp.Type != typeof(string) && tCol != null && tnCol != null)
{
var sourceGenericType = sourceExp.Type.GetGenericArguments()[0];
var destGenericType = destProp.PropertyType.GetGenericArguments()[0];
var destGenericType = destProp.PropertyType.IsArray ? destProp.PropertyType.GetElementType() : destProp.PropertyType.GetGenericArguments()[0];

var genericMemberQueryableExpression =
MappingService.GetMemberQueryableExpression(sourceGenericType,
Expand All @@ -140,16 +139,24 @@ private void ProcessProjectingMember(Expression sourceExp, PropertyInfo destProp

MethodInfo selectMethod = null;
foreach (
var p in from m in typeof (Enumerable).GetMethods().Where(m => m.Name == "Select")
from p in m.GetParameters().Where(p => p.Name.Equals("selector"))
where p.ParameterType.GetGenericArguments().Count() == 2
select p)
selectMethod = (MethodInfo) p.Member;
var p in from m in typeof(Enumerable).GetMethods().Where(m => m.Name == "Select")
from p in m.GetParameters().Where(p => p.Name.Equals("selector"))
where p.ParameterType.GetGenericArguments().Count() == 2
select p)
selectMethod = (MethodInfo)p.Member;

var selectExpression = Expression.Call(
Expression selectExpression = Expression.Call(
null,
selectMethod.MakeGenericMethod(sourceGenericType, destGenericType),
new[] {sourceExp, genericMemberQueryableExpression});
new[] { sourceExp, genericMemberQueryableExpression });

var destListAndCollTest = typeof(ICollection<>).MakeGenericType(destGenericType).IsAssignableFrom(destProp.PropertyType);

if (destListAndCollTest)
{
var toArrayMethod = typeof(Enumerable).GetMethod("ToList");
selectExpression = Expression.Call(null, toArrayMethod.MakeGenericMethod(destGenericType), selectExpression);
}

_bindingExpressions.Add(destProp.Name,
Expression.Bind(destProp, selectExpression));
Expand All @@ -166,14 +173,6 @@ where p.ParameterType.GetGenericArguments().Count() == 2
Expression.Condition(
Expression.Equal(sourceExp, Expression.Constant(null, sourceExp.Type)),
Expression.Constant(null, destProp.PropertyType), clearanceExp);

//var nullCheckNestedMemberVisitor = new NullCheckNestedMemberVisitor(true);
//nullCheckNestedMemberVisitor.Visit(sourceExp);

//expression = nullCheckNestedMemberVisitor.CheckNullExpression != null
// ? Expression.Condition(nullCheckNestedMemberVisitor.CheckNullExpression,
// Expression.Constant(null, destProp.PropertyType), expression)
// : expression;
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,18 @@
<Reference Include="System" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Core" />
<Reference Include="System.IO, Version=2.6.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.1.1.10\lib\net40\System.IO.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Runtime, Version=2.6.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.1.1.10\lib\net40\System.Runtime.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Threading.Tasks, Version=2.6.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.1.1.10\lib\net40\System.Threading.Tasks.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
Expand Down Expand Up @@ -96,7 +108,9 @@
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
<None Include="packages.config">
<SubType>Designer</SubType>
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ExpressMapper NET40\ExpressMapper NET40.csproj">
Expand All @@ -110,6 +124,11 @@
</EmbeddedResource>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets')" />
<Target Name="EnsureBclBuildImported" BeforeTargets="BeforeBuild" Condition="'$(BclBuildImported)' == ''">
<Error Condition="!Exists('..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets')" Text="This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=317567." HelpKeyword="BCLBUILD2001" />
<Error Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets')" Text="The build restored NuGet packages. Build the project again to include these packages in the build. For more information, see http://go.microsoft.com/fwlink/?LinkID=317568." HelpKeyword="BCLBUILD2002" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
Expand Down
10 changes: 5 additions & 5 deletions ExpressMapper.Tests.Projections/Tests/CollectionPropertyTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ private void InitializeData()
{
Id = catalId,
Name = catalName,
Categories = new List<CategoryViewModel>
Categories = new[]
{
cat, cat1
}
Expand All @@ -236,7 +236,7 @@ private void InitializeData()
{
Id = catalId1,
Name = catalName1,
Categories = new List<CategoryViewModel>
Categories = new []
{
cat, cat1, cat2
}
Expand Down Expand Up @@ -347,14 +347,14 @@ private List<CatalogueGroupViewModel> SortCollections(List<CatalogueGroupViewMod
{
if (e.Products != null)
{
e.Products = e.Products.OrderBy(p => p.Id);
e.Products = e.Products.OrderBy(p => p.Id).ToList();
}
}
);
v.Categories = v.Categories.OrderBy(f => f.Id);
v.Categories = v.Categories.OrderBy(f => f.Id).ToArray();
}
});
r.Catalogues = r.Catalogues.OrderBy(s => s.Id);
r.Catalogues = r.Catalogues.OrderBy(s => s.Id).ToList();
});
return list.OrderBy(r => r.Id).ToList();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public CatalogueGroupViewModel()

public Guid Id { get; set; }
public string Name { get; set; }
public IEnumerable<CatalogueViewModel> Catalogues { get; set; }
public List<CatalogueViewModel> Catalogues { get; set; }

public bool Equals(CatalogueGroupViewModel other)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public CatalogueViewModel()
}
public Guid Id { get; set; }
public string Name { get; set; }
public IEnumerable<CategoryViewModel> Categories { get; set; }
public IList<CategoryViewModel> Categories { get; set; }

public bool Equals(CatalogueViewModel other)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public CategoryViewModel()
public Guid Id { get; set; }
public string Name { get; set; }

public IEnumerable<ProductViewModel> Products { get; set; }
public ICollection<ProductViewModel> Products { get; set; }

public bool Equals(CategoryViewModel other)
{
Expand Down

0 comments on commit a144e75

Please sign in to comment.