well advanced to start new way of null checking.
This commit is contained in:
		
							parent
							
								
									10f15b802c
								
							
						
					
					
						commit
						b80e9e433c
					
				
							
								
								
									
										6
									
								
								PoweredSoft.DynamicLinq.ConsoleApp/App.config
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								PoweredSoft.DynamicLinq.ConsoleApp/App.config
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | ||||
| <?xml version="1.0" encoding="utf-8" ?> | ||||
| <configuration> | ||||
|     <startup>  | ||||
|         <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" /> | ||||
|     </startup> | ||||
| </configuration> | ||||
| @ -0,0 +1,66 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||||
|   <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> | ||||
|   <PropertyGroup> | ||||
|     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> | ||||
|     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> | ||||
|     <ProjectGuid>{A166BD89-7BF3-475B-871F-294B8A420D9E}</ProjectGuid> | ||||
|     <OutputType>Exe</OutputType> | ||||
|     <RootNamespace>PoweredSoft.DynamicLinq.ConsoleApp</RootNamespace> | ||||
|     <AssemblyName>PoweredSoft.DynamicLinq.ConsoleApp</AssemblyName> | ||||
|     <TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion> | ||||
|     <FileAlignment>512</FileAlignment> | ||||
|     <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> | ||||
|   </PropertyGroup> | ||||
|   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> | ||||
|     <PlatformTarget>AnyCPU</PlatformTarget> | ||||
|     <DebugSymbols>true</DebugSymbols> | ||||
|     <DebugType>full</DebugType> | ||||
|     <Optimize>false</Optimize> | ||||
|     <OutputPath>bin\Debug\</OutputPath> | ||||
|     <DefineConstants>DEBUG;TRACE</DefineConstants> | ||||
|     <ErrorReport>prompt</ErrorReport> | ||||
|     <WarningLevel>4</WarningLevel> | ||||
|   </PropertyGroup> | ||||
|   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> | ||||
|     <PlatformTarget>AnyCPU</PlatformTarget> | ||||
|     <DebugType>pdbonly</DebugType> | ||||
|     <Optimize>true</Optimize> | ||||
|     <OutputPath>bin\Release\</OutputPath> | ||||
|     <DefineConstants>TRACE</DefineConstants> | ||||
|     <ErrorReport>prompt</ErrorReport> | ||||
|     <WarningLevel>4</WarningLevel> | ||||
|   </PropertyGroup> | ||||
|   <ItemGroup> | ||||
|     <Reference Include="System" /> | ||||
|     <Reference Include="System.Core" /> | ||||
|     <Reference Include="System.Xml.Linq" /> | ||||
|     <Reference Include="System.Data.DataSetExtensions" /> | ||||
|     <Reference Include="Microsoft.CSharp" /> | ||||
|     <Reference Include="System.Data" /> | ||||
|     <Reference Include="System.Net.Http" /> | ||||
|     <Reference Include="System.Xml" /> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <Compile Include="Program.cs" /> | ||||
|     <Compile Include="Properties\AssemblyInfo.cs" /> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <None Include="App.config" /> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <ProjectReference Include="..\PoweredSoft.DynamicLinq.Dal\PoweredSoft.DynamicLinq.Dal.csproj"> | ||||
|       <Project>{c16927e7-1358-4b9d-bdd7-149e505de6cc}</Project> | ||||
|       <Name>PoweredSoft.DynamicLinq.Dal</Name> | ||||
|     </ProjectReference> | ||||
|     <ProjectReference Include="..\PoweredSoft.DynamicLinq.Test\PoweredSoft.DynamicLinq.Test.csproj"> | ||||
|       <Project>{6f5c80f0-9045-4098-913f-7bdad135e6dd}</Project> | ||||
|       <Name>PoweredSoft.DynamicLinq.Test</Name> | ||||
|     </ProjectReference> | ||||
|     <ProjectReference Include="..\PoweredSoft.DynamicLinq\PoweredSoft.DynamicLinq.csproj"> | ||||
|       <Project>{5bb7e50f-8b40-4512-88dc-4b3bd89c9a5e}</Project> | ||||
|       <Name>PoweredSoft.DynamicLinq</Name> | ||||
|     </ProjectReference> | ||||
|   </ItemGroup> | ||||
|   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> | ||||
| </Project> | ||||
							
								
								
									
										50
									
								
								PoweredSoft.DynamicLinq.ConsoleApp/Program.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								PoweredSoft.DynamicLinq.ConsoleApp/Program.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,50 @@ | ||||
| using PoweredSoft.DynamicLinq.Helpers; | ||||
| using PoweredSoft.DynamicLinq.Test; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Linq.Expressions; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
| 
 | ||||
| namespace PoweredSoft.DynamicLinq.ConsoleApp | ||||
| { | ||||
|     public class Program | ||||
|     { | ||||
|         static void Main(string[] args) | ||||
|         { | ||||
|             var type = typeof(Dal.Pocos.Author); | ||||
|             var param = Expression.Parameter(type); | ||||
|             var path = "Posts.Comments.Id"; | ||||
|             var expr = ResolveSelectExpression(param, path, SelectCollectionHandling.Flatten); | ||||
|             var expr2 = ResolveSelectExpression(param, path, SelectCollectionHandling.Flatten, true); | ||||
|         } | ||||
| 
 | ||||
|         public static Expression ResolveSelectExpression(ParameterExpression param, string path, SelectCollectionHandling selectCollectionHandling = SelectCollectionHandling.LeaveAsIs, bool nullChecking = false) | ||||
|         { | ||||
|             var notCheckNullExpression = QueryablePathHelpers.NavigatePath(param, path,  | ||||
|                 (before, member, isFirst, isLast) => member,  | ||||
|                 (before, member, isFirst, isLast) => member, | ||||
|                 (parent, innerExpression, innerExpressionLambda) => | ||||
|                 { | ||||
|                     var listGenericArgumentType = parent.Type.GetGenericArguments().First(); | ||||
|                     Expression ret = null; | ||||
|                     if (selectCollectionHandling == SelectCollectionHandling.LeaveAsIs || !QueryableHelpers.IsGenericEnumerable(innerExpression)) | ||||
|                         ret = Expression.Call(typeof(Enumerable), "Select", new Type[] { listGenericArgumentType, innerExpression.Type }, parent, innerExpressionLambda); | ||||
|                     else | ||||
|                         ret = Expression.Call(typeof(Enumerable), "SelectMany", new Type[] { listGenericArgumentType, innerExpression.Type.GenericTypeArguments.First() }, parent, innerExpressionLambda); | ||||
| 
 | ||||
|                     return ret; | ||||
|                 } | ||||
|             ); | ||||
| 
 | ||||
|             if (!nullChecking) | ||||
|                 return notCheckNullExpression; | ||||
| 
 | ||||
|             var type = notCheckNullExpression.Type; | ||||
|             throw new NotSupportedException(); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,36 @@ | ||||
| using System.Reflection; | ||||
| using System.Runtime.CompilerServices; | ||||
| using System.Runtime.InteropServices; | ||||
| 
 | ||||
| // General Information about an assembly is controlled through the following | ||||
| // set of attributes. Change these attribute values to modify the information | ||||
| // associated with an assembly. | ||||
| [assembly: AssemblyTitle("PoweredSoft.DynamicLinq.ConsoleApp")] | ||||
| [assembly: AssemblyDescription("")] | ||||
| [assembly: AssemblyConfiguration("")] | ||||
| [assembly: AssemblyCompany("")] | ||||
| [assembly: AssemblyProduct("PoweredSoft.DynamicLinq.ConsoleApp")] | ||||
| [assembly: AssemblyCopyright("Copyright ©  2018")] | ||||
| [assembly: AssemblyTrademark("")] | ||||
| [assembly: AssemblyCulture("")] | ||||
| 
 | ||||
| // Setting ComVisible to false makes the types in this assembly not visible | ||||
| // to COM components.  If you need to access a type in this assembly from | ||||
| // COM, set the ComVisible attribute to true on that type. | ||||
| [assembly: ComVisible(false)] | ||||
| 
 | ||||
| // The following GUID is for the ID of the typelib if this project is exposed to COM | ||||
| [assembly: Guid("a166bd89-7bf3-475b-871f-294b8a420d9e")] | ||||
| 
 | ||||
| // Version information for an assembly consists of the following four values: | ||||
| // | ||||
| //      Major Version | ||||
| //      Minor Version | ||||
| //      Build Number | ||||
| //      Revision | ||||
| // | ||||
| // You can specify all the values or you can default the Build and Revision Numbers | ||||
| // by using the '*' as shown below: | ||||
| // [assembly: AssemblyVersion("1.0.*")] | ||||
| [assembly: AssemblyVersion("1.0.0.0")] | ||||
| [assembly: AssemblyFileVersion("1.0.0.0")] | ||||
| @ -57,8 +57,8 @@ namespace PoweredSoft.DynamicLinq.Test | ||||
|                 .Select(t => | ||||
|                 { | ||||
|                     t.Path("Id"); | ||||
|                     t.PathToList("Bs.FirstNames", "FirstNames", SelectCollectionHandling.SelectMany); | ||||
|                     t.PathToList("Bs.FirstNames", "FirstNamesLists", SelectCollectionHandling.Select); | ||||
|                     t.PathToList("Bs.FirstNames", "FirstNames", SelectCollectionHandling.Flatten); | ||||
|                     t.PathToList("Bs.FirstNames", "FirstNamesLists", SelectCollectionHandling.LeaveAsIs); | ||||
|                 }) | ||||
|                 .ToDynamicClassList(); | ||||
| 
 | ||||
| @ -94,7 +94,7 @@ namespace PoweredSoft.DynamicLinq.Test | ||||
|             var querySelect = query.Select(t => | ||||
|             { | ||||
|                 t.NullChecking(true); | ||||
|                 t.PathToList("Posts.Comments", selectCollectionHandling: SelectCollectionHandling.SelectMany); | ||||
|                 t.PathToList("Posts.Comments", selectCollectionHandling: SelectCollectionHandling.Flatten); | ||||
|             }); | ||||
| 
 | ||||
|             var list = querySelect.ToDynamicClassList(); | ||||
|  | ||||
| @ -1,15 +1,17 @@ | ||||
|  | ||||
| Microsoft Visual Studio Solution File, Format Version 12.00 | ||||
| # Visual Studio 15 | ||||
| VisualStudioVersion = 15.0.27130.2010 | ||||
| VisualStudioVersion = 15.0.27130.2036 | ||||
| MinimumVisualStudioVersion = 10.0.40219.1 | ||||
| Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PoweredSoft.DynamicLinq", "PoweredSoft.DynamicLinq\PoweredSoft.DynamicLinq.csproj", "{5BB7E50F-8B40-4512-88DC-4B3BD89C9A5E}" | ||||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PoweredSoft.DynamicLinq", "PoweredSoft.DynamicLinq\PoweredSoft.DynamicLinq.csproj", "{5BB7E50F-8B40-4512-88DC-4B3BD89C9A5E}" | ||||
| EndProject | ||||
| Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PoweredSoft.DynamicLinq.Test", "PoweredSoft.DynamicLinq.Test\PoweredSoft.DynamicLinq.Test.csproj", "{6F5C80F0-9045-4098-913F-7BDAD135E6DD}" | ||||
| EndProject | ||||
| Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PoweredSoft.DynamicLinq.Dal", "PoweredSoft.DynamicLinq.Dal\PoweredSoft.DynamicLinq.Dal.csproj", "{C16927E7-1358-4B9D-BDD7-149E505DE6CC}" | ||||
| EndProject | ||||
| Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PoweredSoft.DynamicLinq.EntityFramework", "PoweredSoft.DynamicLinq.EntityFramework\PoweredSoft.DynamicLinq.EntityFramework.csproj", "{82DADDB0-4A69-4E19-82AD-E73ABC8F1B4A}" | ||||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PoweredSoft.DynamicLinq.EntityFramework", "PoweredSoft.DynamicLinq.EntityFramework\PoweredSoft.DynamicLinq.EntityFramework.csproj", "{82DADDB0-4A69-4E19-82AD-E73ABC8F1B4A}" | ||||
| EndProject | ||||
| Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PoweredSoft.DynamicLinq.ConsoleApp", "PoweredSoft.DynamicLinq.ConsoleApp\PoweredSoft.DynamicLinq.ConsoleApp.csproj", "{A166BD89-7BF3-475B-871F-294B8A420D9E}" | ||||
| EndProject | ||||
| Global | ||||
| 	GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||
| @ -33,6 +35,10 @@ Global | ||||
| 		{82DADDB0-4A69-4E19-82AD-E73ABC8F1B4A}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||||
| 		{82DADDB0-4A69-4E19-82AD-E73ABC8F1B4A}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||||
| 		{82DADDB0-4A69-4E19-82AD-E73ABC8F1B4A}.Release|Any CPU.Build.0 = Release|Any CPU | ||||
| 		{A166BD89-7BF3-475B-871F-294B8A420D9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||||
| 		{A166BD89-7BF3-475B-871F-294B8A420D9E}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||||
| 		{A166BD89-7BF3-475B-871F-294B8A420D9E}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||||
| 		{A166BD89-7BF3-475B-871F-294B8A420D9E}.Release|Any CPU.Build.0 = Release|Any CPU | ||||
| 	EndGlobalSection | ||||
| 	GlobalSection(SolutionProperties) = preSolution | ||||
| 		HideSolutionNode = FALSE | ||||
|  | ||||
| @ -55,8 +55,8 @@ namespace PoweredSoft.DynamicLinq | ||||
| 
 | ||||
|     public enum SelectCollectionHandling | ||||
|     { | ||||
|         Select, | ||||
|         SelectMany | ||||
|         LeaveAsIs, | ||||
|         Flatten | ||||
|     } | ||||
| 
 | ||||
|     internal static class Constants | ||||
|  | ||||
| @ -141,7 +141,7 @@ namespace PoweredSoft.DynamicLinq.Fluent | ||||
|             return this; | ||||
|         } | ||||
| 
 | ||||
|         public SelectBuilder PathToList(string path, string propertyName = null, SelectCollectionHandling selectCollectionHandling = SelectCollectionHandling.Select) | ||||
|         public SelectBuilder PathToList(string path, string propertyName = null, SelectCollectionHandling selectCollectionHandling = SelectCollectionHandling.LeaveAsIs) | ||||
|         { | ||||
|             if (propertyName == null) | ||||
|                 propertyName = path.Split('.').LastOrDefault(); | ||||
|  | ||||
| @ -270,7 +270,7 @@ namespace PoweredSoft.DynamicLinq.Helpers | ||||
|                 var innerExpression = InternalResolvePathExpression(step + 1, innerParam, parts.Skip(1).ToList(), selectCollectionHandling, nullChecking); | ||||
|                 var lambda = Expression.Lambda(innerExpression, innerParam); | ||||
| 
 | ||||
|                 if (selectCollectionHandling == SelectCollectionHandling.Select) | ||||
|                 if (selectCollectionHandling == SelectCollectionHandling.LeaveAsIs) | ||||
|                     ret = Expression.Call(typeof(Enumerable), "Select", new Type[] { listGenericArgumentType, innerExpression.Type }, memberExpression, lambda); | ||||
|                 else | ||||
|                     ret = Expression.Call(typeof(Enumerable), "SelectMany", new Type[] { listGenericArgumentType, innerExpression.Type.GenericTypeArguments.First() }, memberExpression, lambda); | ||||
| @ -527,7 +527,7 @@ namespace PoweredSoft.DynamicLinq.Helpers | ||||
|             return result; | ||||
|         } | ||||
| 
 | ||||
|         public static bool IsGenericEnumerable(MemberExpression member) => IsGenericEnumerable(member.Type); | ||||
|         public static bool IsGenericEnumerable(Expression member) => IsGenericEnumerable(member.Type); | ||||
|         public static bool IsGenericEnumerable(Type type) | ||||
|         { | ||||
|             if (!type.IsGenericType) | ||||
|  | ||||
							
								
								
									
										53
									
								
								PoweredSoft.DynamicLinq/Helpers/QueryablePathHelpers.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								PoweredSoft.DynamicLinq/Helpers/QueryablePathHelpers.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,53 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Linq.Expressions; | ||||
| using System.Text; | ||||
| 
 | ||||
| namespace PoweredSoft.DynamicLinq.Helpers | ||||
| { | ||||
|     public static class QueryablePathHelpers | ||||
|     { | ||||
|         public delegate Expression SimplePathNavigated(Expression before, MemberExpression member, bool isFirst, bool isLast); | ||||
|         public delegate Expression CollectionPathNavigated(Expression before, MemberExpression member, bool isFirst, bool isLast); | ||||
|         public delegate Expression CollectionHandling(Expression parent, Expression innerExpression, LambdaExpression innerExpressionLambda); | ||||
| 
 | ||||
|         internal static Expression InternalNavigatePath(Expression before, List<string> parts, SimplePathNavigated simple, CollectionPathNavigated collection, CollectionHandling collectionHandling) | ||||
|         { | ||||
|             var isFirst = before is ParameterExpression; | ||||
|             var isLast = parts.Count() == 1; | ||||
|             var currentExpression = Expression.PropertyOrField(before, parts.First()); | ||||
|             var isEnumerable = QueryableHelpers.IsGenericEnumerable(currentExpression); | ||||
| 
 | ||||
|             // allow interaction through callback. | ||||
|             var alteredExpression = isEnumerable ? simple(before, currentExpression, isFirst, isLast) : collection(before, currentExpression, isFirst, isLast); | ||||
| 
 | ||||
|             // if its last we are done :) | ||||
|             if (isLast) | ||||
|                 return alteredExpression; | ||||
| 
 | ||||
|             // not enumerable pretty simple. | ||||
|             if (!isEnumerable) | ||||
|                 return InternalNavigatePath(alteredExpression, parts.Skip(1).ToList(), simple, collection, collectionHandling); | ||||
| 
 | ||||
|             // enumerable. | ||||
|             var listGenericArgumentType = alteredExpression.Type.GetGenericArguments().First(); | ||||
| 
 | ||||
|             // sub param. | ||||
|             var innerParameter = Expression.Parameter(listGenericArgumentType); | ||||
|             var innerExpr = InternalNavigatePath(innerParameter, parts.Skip(1).ToList(), simple, collection, collectionHandling); | ||||
|             var lambda = Expression.Lambda(innerExpr, innerParameter); | ||||
|             var collectionHandlingResult = collectionHandling(alteredExpression, innerExpr, lambda); | ||||
|             return collectionHandlingResult; | ||||
|         } | ||||
| 
 | ||||
|         public static Expression NavigatePath(ParameterExpression param, string path, | ||||
|             SimplePathNavigated simple, | ||||
|             CollectionPathNavigated collection, | ||||
|              CollectionHandling collectionHandling) | ||||
|         { | ||||
|             var parts = path.Split('.').ToList(); | ||||
|             return InternalNavigatePath(param, parts, simple, collection, collectionHandling); | ||||
|         } | ||||
|     } | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user