├── .gitattributes ├── .gitignore ├── LICENSE.txt ├── LinqToQueryString.IntegrationTests ├── App.config ├── Exceptions.cs ├── LinqToQueryString.IntegrationTests.Sql.csproj ├── Properties │ └── AssemblyInfo.cs ├── SqlCollectionAggregates.cs ├── SqlFiltering.cs ├── SqlFunctions.cs ├── SqlInlineCount.cs ├── SqlPagingAndOrdering.cs ├── SqlProjection.cs ├── TestDbContext.cs └── packages.config ├── LinqToQueryString.Tests ├── ComplexClass.cs ├── ConcreteClass.cs ├── IndexedClass.cs ├── InstanceBuilders.cs ├── LinqToQueryString.Tests.csproj ├── Properties │ └── AssemblyInfo.cs └── RandomDataGenerators.cs ├── LinqToQueryString.UnitTests ├── CollectionAggregates.cs ├── Dynamics.cs ├── Exceptions.cs ├── Filtering.cs ├── Functions.cs ├── InlineCount.cs ├── LinqToQueryString.UnitTests.csproj ├── Options.cs ├── PagingAndOrdering.cs ├── Projection.cs ├── Properties │ └── AssemblyInfo.cs └── packages.config ├── LinqToQuerystring.Core.sln ├── LinqToQuerystring.Demo.Nancy ├── Bootstrapper.cs ├── LinqToQuerystring.Demo.Nancy.csproj ├── Models │ └── Movie.cs ├── MoviesModule.cs ├── Properties │ └── AssemblyInfo.cs ├── Web.Debug.config ├── Web.Release.config ├── Web.config └── packages.config ├── LinqToQuerystring.Demo ├── App_Start │ ├── BundleConfig.cs │ ├── FilterConfig.cs │ ├── RouteConfig.cs │ └── WebApiConfig.cs ├── Content │ └── Site.css ├── Controllers │ ├── HomeController.cs │ └── ValuesController.cs ├── Filters │ └── ApiExceptionFilterAttribute.cs ├── Global.asax ├── Global.asax.cs ├── Images │ ├── accent.png │ ├── bullet.png │ ├── heroAccent.png │ ├── orderedList0.png │ ├── orderedList1.png │ ├── orderedList2.png │ ├── orderedList3.png │ ├── orderedList4.png │ ├── orderedList5.png │ ├── orderedList6.png │ ├── orderedList7.png │ ├── orderedList8.png │ └── orderedList9.png ├── LinqToQuerystring.Demo.csproj ├── Models │ └── Movie.cs ├── Properties │ ├── AssemblyInfo.cs │ └── PublishProfiles │ │ ├── linqtoquerystring - FTP.pubxml │ │ └── linqtoquerystring - Web Deploy.pubxml ├── Scripts │ ├── _references.js │ ├── jquery-1.10.1.js │ ├── jquery-1.10.1.min.js │ ├── jquery-ui-1.8.24.js │ ├── jquery-ui-1.8.24.min.js │ ├── jquery.odatafilterui-0.1.2.js │ ├── jquery.odatafilterui-0.1.2.min.js │ ├── jquery.unobtrusive-ajax.js │ ├── jquery.unobtrusive-ajax.min.js │ ├── jquery.validate-vsdoc.js │ ├── jquery.validate.js │ ├── jquery.validate.min.js │ ├── jquery.validate.unobtrusive.js │ ├── jquery.validate.unobtrusive.min.js │ ├── knockout-2.2.1.debug.js │ ├── knockout-2.2.1.js │ └── modernizr-2.6.2.js ├── Views │ ├── Home │ │ └── Index.cshtml │ ├── Shared │ │ ├── Error.cshtml │ │ └── _Layout.cshtml │ ├── Web.config │ └── _ViewStart.cshtml ├── Web.Debug.config ├── Web.Release.config ├── Web.config ├── favicon.ico └── packages.config ├── LinqToQuerystring.EntityFramework ├── App.config ├── Configuration.cs ├── ExpandNode.cs ├── LinqToQuerystring.EntityFramework.csproj ├── Properties │ └── AssemblyInfo.cs └── packages.config ├── LinqToQuerystring.IntegrationTests.EntityFramework ├── App.config ├── LinqToQuerystring.IntegrationTests.EntityFramework.csproj ├── Properties │ └── AssemblyInfo.cs ├── SqlExpand.cs └── packages.config ├── LinqToQuerystring.IntegrationTests.Mongo ├── ConcreteMongoClass.cs ├── Exceptions.cs ├── InstanceBuilders.cs ├── LinqToQuerystring.IntegrationTests.Mongo.csproj ├── MongoCollectionAggregates.cs ├── MongoDocument.cs ├── MongoDocumentClassSerializer.cs ├── MongoFiltering.cs ├── MongoFunctions.cs ├── MongoInlineCount.cs ├── MongoPagingAndOrdering.cs ├── MongoProjection.cs ├── Properties │ └── AssemblyInfo.cs └── packages.config ├── LinqToQuerystring.IntegrationTests.WebAPI ├── ContentNegotiationTests.cs ├── Controllers │ ├── DataClass.cs │ ├── DataController.cs │ └── NonGenericController.cs ├── CsvMediaTypeFormatter.cs ├── LinqToQuerystring.IntegrationTests.WebApi.csproj ├── LinqToQuerystring.IntegrationTests.WebApi2.csproj ├── Properties │ └── AssemblyInfo.cs ├── QuerySyntaxTests.cs ├── SimpleTracer.cs └── packages.config ├── LinqToQuerystring.Javascript ├── LinqToQuerystring.g ├── antlr3-all-min.js ├── antlr3-all.js ├── antlr3-cli-min.js ├── antlr3-cli.js ├── demo.html └── output │ ├── LinqToQuerystring.tokens │ ├── LinqToQuerystringLexer.js │ └── LinqToQuerystringParser.js ├── LinqToQuerystring.Nancy ├── LinqToQuerystring.Nancy.csproj ├── LinqToQuerystring.Nancy.nuspec ├── NancyExtensions.cs └── Properties │ └── AssemblyInfo.cs ├── LinqToQuerystring.WebApi.sln ├── LinqToQuerystring.WebApi ├── LinqToQueryableAttribute.cs ├── LinqToQuerystring.WebAPI.nuspec ├── LinqToQuerystring.WebAPI2.nuspec ├── LinqToQuerystring.WebApi.csproj ├── LinqToQuerystring.WebApi2.csproj ├── Properties │ └── AssemblyInfo.cs └── packages.config ├── LinqToQuerystring.WebApi2.sln ├── LinqToQuerystring.sln ├── LinqToQuerystring ├── Configuration.cs ├── Exceptions │ ├── FunctionNotSupportedException.cs │ └── InvalidEscapeSequenceException.cs ├── Extensions.cs ├── LinqToQuerystring.csproj ├── LinqToQuerystring.g ├── LinqToQuerystring.nuspec ├── LinqToQuerystring.tokens ├── LinqToQuerystringLexer.cs ├── LinqToQuerystringParser.cs ├── Properties │ └── AssemblyInfo.cs ├── Settings.StyleCop ├── TreeNodes │ ├── Aggregates │ │ ├── AllNode.cs │ │ ├── AnyNode.cs │ │ ├── AverageNode.cs │ │ ├── CountNode.cs │ │ ├── MaxNode.cs │ │ ├── MinNode.cs │ │ └── SumNode.cs │ ├── AliasNode.cs │ ├── AndNode.cs │ ├── AscNode.cs │ ├── Base │ │ ├── ExplicitOrderByBase.cs │ │ ├── QueryModifier.cs │ │ ├── SingleChildNode.cs │ │ ├── TreeNode.cs │ │ └── TwoChildNode.cs │ ├── Comparisons │ │ ├── EqualsNode.cs │ │ ├── GreaterThanNode.cs │ │ ├── GreaterThanOrEqualNode.cs │ │ ├── LessThanNode.cs │ │ ├── LessThanOrEqualNode.cs │ │ └── NotEqualsNode.cs │ ├── DataTypes │ │ ├── BoolNode.cs │ │ ├── ByteNode.cs │ │ ├── DateTimeNode.cs │ │ ├── DecimalNode.cs │ │ ├── DoubleNode.cs │ │ ├── GuidNode.cs │ │ ├── IntNode.cs │ │ ├── LongNode.cs │ │ ├── SingleNode.cs │ │ └── StringNode.cs │ ├── DescNode.cs │ ├── DynamicIdentifierNode.cs │ ├── ExpandNode.cs │ ├── FilterNode.cs │ ├── Functions │ │ ├── DayNode.cs │ │ ├── DaysNode.cs │ │ ├── EndsWithNode.cs │ │ ├── HourNode.cs │ │ ├── HoursNode.cs │ │ ├── MinuteNode.cs │ │ ├── MinutesNode.cs │ │ ├── MonthNode.cs │ │ ├── SecondNode.cs │ │ ├── SecondsNode.cs │ │ ├── StartsWithNode.cs │ │ ├── SubstringOfNode.cs │ │ ├── ToLowerNode.cs │ │ ├── ToUpperNode.cs │ │ ├── YearNode.cs │ │ └── YearsNode.cs │ ├── IdentifierNode.cs │ ├── IgnoredNode.cs │ ├── InlineCountNode.cs │ ├── NotNode.cs │ ├── NullNode.cs │ ├── OrNode.cs │ ├── OrderByNode.cs │ ├── SelectNode.cs │ ├── SkipNode.cs │ ├── TopNode.cs │ └── TreeNodeFactory.cs ├── Utils │ └── CustomNodeMappings.cs └── packages.config ├── README.md └── lib ├── ANTLR ├── Antlr3.Runtime.Debug.dll ├── Antlr3.Runtime.dll ├── Antlr3.exe ├── Antlr3.exe.config ├── Antlr3.targets ├── Antlr4.StringTemplate.Visualizer.dll ├── Antlr4.StringTemplate.dll ├── AntlrBuildTask.dll ├── Codegen │ └── Templates │ │ ├── CSharp3 │ │ ├── AST.stg │ │ ├── ASTDbg.stg │ │ ├── ASTParser.stg │ │ ├── ASTTreeParser.stg │ │ ├── CSharp3.stg │ │ ├── Dbg.stg │ │ └── ST.stg │ │ ├── JavaScript │ │ ├── AST.stg │ │ ├── ASTParser.stg │ │ ├── ASTTreeParser.stg │ │ └── JavaScript.stg │ │ └── LeftRecursiveRules.stg ├── LICENSE.txt ├── Targets │ ├── Antlr3.Targets.CSharp3.dll │ └── Antlr3.Targets.JavaScript.dll └── Tool │ └── Templates │ ├── depend.stg │ ├── dot │ └── dot.stg │ └── messages │ ├── formats │ ├── antlr.stg │ ├── gnu.stg │ └── vs2005.stg │ └── languages │ └── en.stg ├── MongoDB.Bson.dll ├── MongoDB.Bson.xml ├── MongoDB.Driver.XML └── MongoDB.Driver.dll /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | 44 | # Build results 45 | [Dd]ebug/ 46 | [Rr]elease/ 47 | *_i.c 48 | *_p.c 49 | *.ilk 50 | *.meta 51 | *.obj 52 | *.pch 53 | *.pdb 54 | *.pgc 55 | *.pgd 56 | *.rsp 57 | *.sbr 58 | *.tlb 59 | *.tli 60 | *.tlh 61 | *.tmp 62 | *.vspscc 63 | .builds 64 | *.dotCover 65 | *.ncrunchsolution 66 | *.ncrunchproject 67 | 68 | ## TODO: If you have NuGet Package Restore enabled, uncomment this 69 | packages/ 70 | _NCrunch_*/ 71 | 72 | # Visual C++ cache files 73 | ipch/ 74 | *.aps 75 | *.ncb 76 | *.opensdf 77 | *.sdf 78 | 79 | # Visual Studio profiler 80 | *.psess 81 | *.vsp 82 | 83 | # ReSharper is a .NET coding add-in 84 | _ReSharper* 85 | 86 | # Installshield output folder 87 | [Ee]xpress 88 | 89 | # DocProject is a documentation generator add-in 90 | DocProject/buildhelp/ 91 | DocProject/Help/*.HxT 92 | DocProject/Help/*.HxC 93 | DocProject/Help/*.hhc 94 | DocProject/Help/*.hhk 95 | DocProject/Help/*.hhp 96 | DocProject/Help/Html2 97 | DocProject/Help/html 98 | 99 | # Click-Once directory 100 | publish 101 | 102 | # Others 103 | [Bb]in 104 | [Oo]bj 105 | sql 106 | TestResults 107 | *.Cache 108 | ClientBin 109 | stylecop.* 110 | ~$* 111 | *.dbmdl 112 | Generated_Code #added for RIA/Silverlight projects 113 | 114 | # Backup & report files from converting an old project file to a newer 115 | # Visual Studio version. Backup files are not needed, because we have git ;-) 116 | _UpgradeReport_Files/ 117 | Backup*/ 118 | UpgradeLog*.XML 119 | 120 | 121 | 122 | ############ 123 | ## Windows 124 | ############ 125 | 126 | # Windows image file caches 127 | Thumbs.db 128 | 129 | # Folder config file 130 | Desktop.ini 131 | 132 | 133 | ############# 134 | ## Python 135 | ############# 136 | 137 | *.py[co] 138 | 139 | # Packages 140 | *.egg 141 | *.egg-info 142 | dist 143 | build 144 | eggs 145 | parts 146 | bin 147 | var 148 | sdist 149 | develop-eggs 150 | .installed.cfg 151 | 152 | # Installer logs 153 | pip-log.txt 154 | 155 | # Unit test / coverage reports 156 | .coverage 157 | .tox 158 | 159 | #Translations 160 | *.mo 161 | 162 | #Mr Developer 163 | .mr.developer.cfg 164 | 165 | # Mac crap 166 | .DS_Store 167 | NuGetPackage/ 168 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Peter Smith 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so, 8 | subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /LinqToQueryString.IntegrationTests/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /LinqToQueryString.IntegrationTests/Exceptions.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQueryString.IntegrationTests.Sql 2 | { 3 | using System; 4 | using System.Data; 5 | using System.Linq; 6 | 7 | using LinqToQuerystring; 8 | 9 | using Machine.Specifications; 10 | 11 | public class When_using_skip_on_unordered_data : SqlPagingAndOrdering 12 | { 13 | private static Exception ex; 14 | 15 | private Because of = () => ex = Catch.Exception(() => result = testDb.ConcreteCollection.LinqToQuerystring("?$skip=1").ToList()); 16 | 17 | private It should_throw_an_exception = () => ex.ShouldBeOfType(); 18 | } 19 | 20 | public class When_trying_to_order_by_complex_types : SqlPagingAndOrdering 21 | { 22 | private static Exception ex; 23 | 24 | private Because of = () => ex = Catch.Exception(() => complexResult = testDb.ComplexCollection.LinqToQuerystring("?$orderby=concrete").ToList()); 25 | 26 | private It should_throw_an_exception = () => ex.ShouldBeOfType(); 27 | } 28 | 29 | public class When_filtering_on_endswith_function : SqlFunctions 30 | { 31 | private static Exception ex; 32 | 33 | private Because of = () => ex = Catch.Exception(() => testDb.ConcreteCollection.LinqToQuerystring("?$filter=endswith(Name,'day')").ToList()); 34 | 35 | private It should_throw_an_exception = () => ex.ShouldBeOfType(); 36 | 37 | private It should_fail_due_to_SQL_CE_not_supporting_endswith = 38 | () => 39 | ex.InnerException.Message.ShouldEqual("The function 'Reverse' is not supported by SQL Server Compact."); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /LinqToQueryString.IntegrationTests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("LinqToQueryString.IntegrationTests.Sql")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("LinqToQueryString")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("d3add83d-6f36-402d-8ac7-7fb1beda13dd")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /LinqToQueryString.IntegrationTests/TestDbContext.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQueryString.IntegrationTests.Sql 2 | { 3 | using System.Data.Entity; 4 | 5 | using LinqToQueryString.Tests; 6 | 7 | public class TestDbContext : DbContext 8 | { 9 | public DbSet ConcreteCollection { get; set; } 10 | 11 | public DbSet ComplexCollection { get; set; } 12 | 13 | public DbSet EdgeCaseCollection { get; set; } 14 | 15 | public DbSet NullableCollection { get; set; } 16 | 17 | public DbSet NullableContainers { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /LinqToQueryString.IntegrationTests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /LinqToQueryString.Tests/ComplexClass.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQueryString.Tests 2 | { 3 | using System.Collections.Generic; 4 | 5 | public class ComplexClass 6 | { 7 | public int Id { get; set; } 8 | 9 | public ConcreteClass Concrete { get; set; } 10 | 11 | public List StringCollection { get; set; } 12 | 13 | public List ConcreteCollection { get; set; } 14 | 15 | public string Title { get; set; } 16 | 17 | public List IntCollection { get; set; } 18 | } 19 | 20 | public class ComplexClassDto 21 | { 22 | public int Id { get; set; } 23 | 24 | public ConcreteClass Concrete { get; set; } 25 | 26 | public IEnumerable StringCollection { get; set; } 27 | 28 | public List ConcreteCollection { get; set; } 29 | 30 | public string Title { get; set; } 31 | 32 | public IEnumerable IntCollection { get; set; } 33 | } 34 | 35 | public class NullableClassDto 36 | { 37 | public IEnumerable NullableCollection { get; set; } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /LinqToQueryString.Tests/ConcreteClass.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQueryString.Tests 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | 6 | public class ConcreteClass : IComparable 7 | { 8 | public ConcreteClass() 9 | { 10 | Date = DateTime.UtcNow; 11 | } 12 | 13 | public int Id { get; set; } 14 | 15 | public string Name { get; set; } 16 | 17 | public DateTime Date { get; set; } 18 | 19 | public bool Complete { get; set; } 20 | 21 | public int Age { get; set; } 22 | 23 | public List Children { get; set; } 24 | 25 | public IEnumerable StringCollection { get; set; } 26 | 27 | public long Population { get; set; } 28 | 29 | public double Value { get; set; } 30 | 31 | public float Cost { get; set; } 32 | 33 | public byte Code { get; set; } 34 | 35 | public Guid Guid { get; set; } 36 | 37 | public decimal Score { get; set; } 38 | 39 | public int CompareTo(ConcreteClass other) 40 | { 41 | return String.CompareOrdinal(this.Name, other.Name); 42 | } 43 | } 44 | 45 | public class EdgeCaseClass : IComparable 46 | { 47 | public EdgeCaseClass() 48 | { 49 | Date = DateTime.UtcNow; 50 | } 51 | 52 | public int Id { get; set; } 53 | 54 | public string Name { get; set; } 55 | 56 | public DateTime Date { get; set; } 57 | 58 | public bool Complete { get; set; } 59 | 60 | public int Age { get; set; } 61 | 62 | public int CompareTo(EdgeCaseClass other) 63 | { 64 | return String.CompareOrdinal(this.Name, other.Name); 65 | } 66 | } 67 | 68 | public class NullableContainer 69 | { 70 | public int Id { get; set; } 71 | 72 | public string Name { get; set; } 73 | 74 | public List Nullables { get; set; } 75 | } 76 | 77 | public class NullableValue 78 | { 79 | public int Id { get; set; } 80 | 81 | public int? Age { get; set; } 82 | } 83 | 84 | public class NullableClass 85 | { 86 | public int? Id { get; set; } 87 | 88 | public DateTime? Date { get; set; } 89 | 90 | public int? Age { get; set; } 91 | 92 | public bool? Complete { get; set; } 93 | 94 | public long? Population { get; set; } 95 | 96 | public double? Value { get; set; } 97 | 98 | public float? Cost { get; set; } 99 | 100 | public byte? Code { get; set; } 101 | 102 | public Guid? Guid { get; set; } 103 | 104 | public List NullableInts { get; set; } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /LinqToQueryString.Tests/IndexedClass.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQueryString.Tests 2 | { 3 | using System.Collections.Generic; 4 | 5 | public class IndexedClass 6 | { 7 | private readonly Dictionary dictionary; 8 | 9 | public IndexedClass(Dictionary dictionary) 10 | { 11 | this.dictionary = dictionary; 12 | } 13 | 14 | public object this[string index] 15 | { 16 | get 17 | { 18 | return this.dictionary[index]; 19 | } 20 | set 21 | { 22 | this.dictionary[index] = value; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /LinqToQueryString.Tests/InstanceBuilders.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQueryString.Tests 2 | { 3 | using System; 4 | 5 | public static class InstanceBuilders 6 | { 7 | public static ConcreteClass BuildConcrete(string name, int age, DateTime date, bool complete) 8 | { 9 | return new ConcreteClass { Name = name, Date = date, Age = age, Complete = complete }; 10 | } 11 | 12 | public static EdgeCaseClass BuildEdgeCase(string name, int age, DateTime date, bool complete) 13 | { 14 | return new EdgeCaseClass { Name = name, Date = date, Age = age, Complete = complete }; 15 | } 16 | 17 | public static ConcreteClass BuildConcrete(string name, int age, DateTime date, bool complete, long population, double value, float cost, byte code, decimal score, Guid guid) 18 | { 19 | return new ConcreteClass { Name = name, Date = date, Age = age, Complete = complete, Population = population, Value = value, Cost = cost, Code = code, Score = score, Guid = guid }; 20 | } 21 | 22 | public static NullableClass BuildNull() 23 | { 24 | return new NullableClass(); 25 | } 26 | 27 | public static NullableClass BuildNull(int? age, DateTime? date, bool? complete, long? population, double? value, float? cost, byte? code, Guid? guid) 28 | { 29 | return new NullableClass { Date = date, Age = age, Complete = complete, Population = population, Value = value, Cost = cost, Code = code, Guid = guid }; 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /LinqToQueryString.Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("LinqToQueryString.Tests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("LinqToQueryString.Tests")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("099dce67-e299-4269-94a8-56cc7194af8e")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /LinqToQueryString.Tests/RandomDataGenerators.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQueryString.Tests 2 | { 3 | using System; 4 | 5 | public static class RandomDataGenerators 6 | { 7 | private static readonly Random Random = new Random(); 8 | 9 | public static string String() 10 | { 11 | return Guid.NewGuid().ToString(); 12 | } 13 | 14 | public static int Int(int min, int max) 15 | { 16 | return Random.Next(min, max); 17 | } 18 | 19 | public static long Long() 20 | { 21 | return Random.Next(10000, 999999); 22 | } 23 | 24 | public static long Long(int min, int max) 25 | { 26 | return Random.Next(min, max); 27 | } 28 | 29 | public static Guid NewGuid() 30 | { 31 | return Guid.NewGuid(); 32 | } 33 | 34 | public static DateTime DateAndTime() 35 | { 36 | var start = new DateTime(1995, 1, 1); 37 | var range = (int)(DateTime.Today - start).TotalDays; 38 | return start.AddDays(Random.Next(range)); 39 | } 40 | 41 | public static bool Bool() 42 | { 43 | return Random.Next(0, 1) > 0; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /LinqToQueryString.UnitTests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("LinqToQueryString.UnitTests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("LinqToQueryString.UnitTests")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("7a619991-aea1-4715-987d-e76198f0d699")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /LinqToQueryString.UnitTests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /LinqToQuerystring.Demo.Nancy/Bootstrapper.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.Demo.Nancy 2 | { 3 | using global::Nancy; 4 | using global::Nancy.Bootstrapper; 5 | using global::Nancy.Diagnostics; 6 | using global::Nancy.TinyIoc; 7 | 8 | public class Bootstrapper : DefaultNancyBootstrapper 9 | { 10 | protected override DiagnosticsConfiguration DiagnosticsConfiguration 11 | { 12 | get { return new DiagnosticsConfiguration { Password = @"password" }; } 13 | } 14 | 15 | protected override void ApplicationStartup(TinyIoCContainer container, IPipelines pipelines) 16 | { 17 | StaticConfiguration.EnableRequestTracing = true; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /LinqToQuerystring.Demo.Nancy/Models/Movie.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.Demo.Models 2 | { 3 | using System; 4 | 5 | public class Movie 6 | { 7 | public string Title { get; set; } 8 | 9 | public int DurationInMinutes { get; set; } 10 | 11 | public DateTime ReleaseDate { get; set; } 12 | 13 | public string Director { get; set; } 14 | 15 | public int MetaScore { get; set; } 16 | 17 | public bool Recommended { get; set; } 18 | } 19 | } -------------------------------------------------------------------------------- /LinqToQuerystring.Demo.Nancy/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("LinqToQuerystring.Demo.Nancy")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("LinqToQuerystring.Demo.Nancy")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("92a4fb3b-8056-4b3a-9970-7718f301757c")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Revision and Build Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /LinqToQuerystring.Demo.Nancy/Web.Debug.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 29 | 30 | -------------------------------------------------------------------------------- /LinqToQuerystring.Demo.Nancy/Web.Release.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 19 | 30 | 31 | -------------------------------------------------------------------------------- /LinqToQuerystring.Demo.Nancy/Web.config: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /LinqToQuerystring.Demo.Nancy/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /LinqToQuerystring.Demo/App_Start/BundleConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Web; 2 | using System.Web.Optimization; 3 | 4 | namespace LinqToQuerystring.Demo 5 | { 6 | public class BundleConfig 7 | { 8 | // For more information on Bundling, visit http://go.microsoft.com/fwlink/?LinkId=254725 9 | public static void RegisterBundles(BundleCollection bundles) 10 | { 11 | bundles.Add(new ScriptBundle("~/bundles/jquery").Include( 12 | "~/Scripts/jquery-{version}.js")); 13 | 14 | bundles.Add(new ScriptBundle("~/bundles/jqueryui").Include( 15 | "~/Scripts/jquery-ui-{version}.js")); 16 | 17 | bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include( 18 | "~/Scripts/jquery.unobtrusive*", 19 | "~/Scripts/jquery.validate*")); 20 | 21 | bundles.Add(new ScriptBundle("~/bundles/knockout").Include( 22 | "~/Scripts/knockout-{version}.js")); 23 | 24 | bundles.Add(new ScriptBundle("~/bundles/odata").Include( 25 | "~/Scripts/jquery.ODataFilterUI*")); 26 | 27 | // Use the development version of Modernizr to develop with and learn from. Then, when you're 28 | // ready for production, use the build tool at http://modernizr.com to pick only the tests you need. 29 | bundles.Add(new ScriptBundle("~/bundles/modernizr").Include( 30 | "~/Scripts/modernizr-*")); 31 | 32 | bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/site.css")); 33 | 34 | bundles.Add(new StyleBundle("~/Content/themes/base/css").Include( 35 | "~/Content/themes/base/jquery.ui.core.css", 36 | "~/Content/themes/base/jquery.ui.resizable.css", 37 | "~/Content/themes/base/jquery.ui.selectable.css", 38 | "~/Content/themes/base/jquery.ui.accordion.css", 39 | "~/Content/themes/base/jquery.ui.autocomplete.css", 40 | "~/Content/themes/base/jquery.ui.button.css", 41 | "~/Content/themes/base/jquery.ui.dialog.css", 42 | "~/Content/themes/base/jquery.ui.slider.css", 43 | "~/Content/themes/base/jquery.ui.tabs.css", 44 | "~/Content/themes/base/jquery.ui.datepicker.css", 45 | "~/Content/themes/base/jquery.ui.progressbar.css", 46 | "~/Content/themes/base/jquery.ui.theme.css")); 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /LinqToQuerystring.Demo/App_Start/FilterConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Web.Mvc; 2 | 3 | namespace LinqToQuerystring.Demo 4 | { 5 | public class FilterConfig 6 | { 7 | public static void RegisterGlobalFilters(GlobalFilterCollection filters) 8 | { 9 | 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /LinqToQuerystring.Demo/App_Start/RouteConfig.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Web.Mvc; 6 | using System.Web.Routing; 7 | 8 | namespace LinqToQuerystring.Demo 9 | { 10 | public class RouteConfig 11 | { 12 | public static void RegisterRoutes(RouteCollection routes) 13 | { 14 | routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 15 | 16 | routes.MapRoute( 17 | name: "Default", 18 | url: "{controller}/{action}/{id}", 19 | defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } 20 | ); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /LinqToQuerystring.Demo/App_Start/WebApiConfig.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.Demo 2 | { 3 | using System.Web.Http; 4 | 5 | public static class WebApiConfig 6 | { 7 | public static void Register(HttpConfiguration config) 8 | { 9 | config.Routes.MapHttpRoute( 10 | name: "DefaultApi", 11 | routeTemplate: "api/{controller}/{id}", 12 | defaults: new { id = RouteParameter.Optional } 13 | ); 14 | 15 | // Uncomment the following line of code to enable query support for actions with an IQueryable or IQueryable return type. 16 | // To avoid processing unexpected or malicious queries, use the validation settings on QueryableAttribute to validate incoming queries. 17 | // For more information, visit http://go.microsoft.com/fwlink/?LinkId=279712. 18 | //config.EnableQuerySupport(); 19 | 20 | // To disable tracing in your application, please comment out or remove the following line of code 21 | // For more information, refer to: http://www.asp.net/web-api 22 | config.EnableSystemDiagnosticsTracing(); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /LinqToQuerystring.Demo/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.Demo.Controllers 2 | { 3 | using System.Web.Mvc; 4 | 5 | public class HomeController : Controller 6 | { 7 | public ActionResult Index() 8 | { 9 | return View(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /LinqToQuerystring.Demo/Filters/ApiExceptionFilterAttribute.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.Demo.Filters 2 | { 3 | using System; 4 | using System.Net; 5 | using System.Net.Http; 6 | using System.Web.Http.Filters; 7 | 8 | public class ApiExceptionFilterAttribute : ExceptionFilterAttribute 9 | { 10 | public override void OnException(HttpActionExecutedContext actionExecutedContext) 11 | { 12 | var argumentException = actionExecutedContext.Exception as Exception; 13 | if (argumentException != null) 14 | { 15 | var message = string.IsNullOrEmpty(argumentException.Message) 16 | ? "An exception occurred" 17 | : argumentException.Message; 18 | 19 | actionExecutedContext.Response = actionExecutedContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, message); 20 | actionExecutedContext.Response.Content.Headers.ContentType = 21 | actionExecutedContext.Request.Content.Headers.ContentType; 22 | } 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /LinqToQuerystring.Demo/Global.asax: -------------------------------------------------------------------------------- 1 | <%@ Application Codebehind="Global.asax.cs" Inherits="LinqToQuerystring.Demo.WebApiApplication" Language="C#" %> 2 | -------------------------------------------------------------------------------- /LinqToQuerystring.Demo/Global.asax.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Web.Http; 6 | using System.Web.Mvc; 7 | using System.Web.Optimization; 8 | using System.Web.Routing; 9 | 10 | namespace LinqToQuerystring.Demo 11 | { 12 | // Note: For instructions on enabling IIS6 or IIS7 classic mode, 13 | // visit http://go.microsoft.com/?LinkId=9394801 14 | 15 | public class WebApiApplication : System.Web.HttpApplication 16 | { 17 | protected void Application_Start() 18 | { 19 | AreaRegistration.RegisterAllAreas(); 20 | 21 | WebApiConfig.Register(GlobalConfiguration.Configuration); 22 | FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 23 | RouteConfig.RegisterRoutes(RouteTable.Routes); 24 | BundleConfig.RegisterBundles(BundleTable.Bundles); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /LinqToQuerystring.Demo/Images/accent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beyond-code-github/LinqToQuerystring/f10c41a86eced0f2cee830f07e8fc71e35496345/LinqToQuerystring.Demo/Images/accent.png -------------------------------------------------------------------------------- /LinqToQuerystring.Demo/Images/bullet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beyond-code-github/LinqToQuerystring/f10c41a86eced0f2cee830f07e8fc71e35496345/LinqToQuerystring.Demo/Images/bullet.png -------------------------------------------------------------------------------- /LinqToQuerystring.Demo/Images/heroAccent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beyond-code-github/LinqToQuerystring/f10c41a86eced0f2cee830f07e8fc71e35496345/LinqToQuerystring.Demo/Images/heroAccent.png -------------------------------------------------------------------------------- /LinqToQuerystring.Demo/Images/orderedList0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beyond-code-github/LinqToQuerystring/f10c41a86eced0f2cee830f07e8fc71e35496345/LinqToQuerystring.Demo/Images/orderedList0.png -------------------------------------------------------------------------------- /LinqToQuerystring.Demo/Images/orderedList1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beyond-code-github/LinqToQuerystring/f10c41a86eced0f2cee830f07e8fc71e35496345/LinqToQuerystring.Demo/Images/orderedList1.png -------------------------------------------------------------------------------- /LinqToQuerystring.Demo/Images/orderedList2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beyond-code-github/LinqToQuerystring/f10c41a86eced0f2cee830f07e8fc71e35496345/LinqToQuerystring.Demo/Images/orderedList2.png -------------------------------------------------------------------------------- /LinqToQuerystring.Demo/Images/orderedList3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beyond-code-github/LinqToQuerystring/f10c41a86eced0f2cee830f07e8fc71e35496345/LinqToQuerystring.Demo/Images/orderedList3.png -------------------------------------------------------------------------------- /LinqToQuerystring.Demo/Images/orderedList4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beyond-code-github/LinqToQuerystring/f10c41a86eced0f2cee830f07e8fc71e35496345/LinqToQuerystring.Demo/Images/orderedList4.png -------------------------------------------------------------------------------- /LinqToQuerystring.Demo/Images/orderedList5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beyond-code-github/LinqToQuerystring/f10c41a86eced0f2cee830f07e8fc71e35496345/LinqToQuerystring.Demo/Images/orderedList5.png -------------------------------------------------------------------------------- /LinqToQuerystring.Demo/Images/orderedList6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beyond-code-github/LinqToQuerystring/f10c41a86eced0f2cee830f07e8fc71e35496345/LinqToQuerystring.Demo/Images/orderedList6.png -------------------------------------------------------------------------------- /LinqToQuerystring.Demo/Images/orderedList7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beyond-code-github/LinqToQuerystring/f10c41a86eced0f2cee830f07e8fc71e35496345/LinqToQuerystring.Demo/Images/orderedList7.png -------------------------------------------------------------------------------- /LinqToQuerystring.Demo/Images/orderedList8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beyond-code-github/LinqToQuerystring/f10c41a86eced0f2cee830f07e8fc71e35496345/LinqToQuerystring.Demo/Images/orderedList8.png -------------------------------------------------------------------------------- /LinqToQuerystring.Demo/Images/orderedList9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beyond-code-github/LinqToQuerystring/f10c41a86eced0f2cee830f07e8fc71e35496345/LinqToQuerystring.Demo/Images/orderedList9.png -------------------------------------------------------------------------------- /LinqToQuerystring.Demo/Models/Movie.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.Demo.Models 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | 6 | public class Movie 7 | { 8 | public string Title { get; set; } 9 | 10 | public int DurationInMinutes { get; set; } 11 | 12 | public DateTime ReleaseDate { get; set; } 13 | 14 | public string Director { get; set; } 15 | 16 | public int MetaScore { get; set; } 17 | 18 | public bool Recommended { get; set; } 19 | 20 | public List Tags { get; set; } 21 | 22 | public List UserScores { get; set; } 23 | } 24 | } -------------------------------------------------------------------------------- /LinqToQuerystring.Demo/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("LinqToQuerystring.Demo")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("LinqToQuerystring.Demo")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("71dcf2b6-920d-4683-b6f1-e92d7e851442")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Revision and Build Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /LinqToQuerystring.Demo/Properties/PublishProfiles/linqtoquerystring - FTP.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 8 | FTP 9 | Release 10 | Any CPU 11 | http://linqtoquerystring.azurewebsites.net 12 | False 13 | ftp://waws-prod-am2-001.ftp.azurewebsites.windows.net 14 | False 15 | True 16 | site/wwwroot 17 | linqtoquerystring\$linqtoquerystring 18 | <_SavePWD>True 19 | 20 | -------------------------------------------------------------------------------- /LinqToQuerystring.Demo/Properties/PublishProfiles/linqtoquerystring - Web Deploy.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 8 | MSDeploy 9 | Release 10 | Any CPU 11 | http://linqtoquerystring.azurewebsites.net 12 | False 13 | waws-prod-am2-001.publish.azurewebsites.windows.net:443 14 | linqtoquerystring 15 | 16 | True 17 | WMSVC 18 | True 19 | $linqtoquerystring 20 | <_SavePWD>True 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | False 39 | 40 | 41 | -------------------------------------------------------------------------------- /LinqToQuerystring.Demo/Scripts/_references.js: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | /// 5 | /// 6 | /// 7 | -------------------------------------------------------------------------------- /LinqToQuerystring.Demo/Scripts/jquery.unobtrusive-ajax.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | ** Unobtrusive Ajax support library for jQuery 3 | ** Copyright (C) Microsoft Corporation. All rights reserved. 4 | */ 5 | (function(a){var b="unobtrusiveAjaxClick",g="unobtrusiveValidation";function c(d,b){var a=window,c=(d||"").split(".");while(a&&c.length)a=a[c.shift()];if(typeof a==="function")return a;b.push(d);return Function.constructor.apply(null,b)}function d(a){return a==="GET"||a==="POST"}function f(b,a){!d(a)&&b.setRequestHeader("X-HTTP-Method-Override",a)}function h(c,b,e){var d;if(e.indexOf("application/x-javascript")!==-1)return;d=(c.getAttribute("data-ajax-mode")||"").toUpperCase();a(c.getAttribute("data-ajax-update")).each(function(f,c){var e;switch(d){case"BEFORE":e=c.firstChild;a("
").html(b).contents().each(function(){c.insertBefore(this,e)});break;case"AFTER":a("
").html(b).contents().each(function(){c.appendChild(this)});break;default:a(c).html(b)}})}function e(b,e){var j,k,g,i;j=b.getAttribute("data-ajax-confirm");if(j&&!window.confirm(j))return;k=a(b.getAttribute("data-ajax-loading"));i=b.getAttribute("data-ajax-loading-duration")||0;a.extend(e,{type:b.getAttribute("data-ajax-method")||undefined,url:b.getAttribute("data-ajax-url")||undefined,beforeSend:function(d){var a;f(d,g);a=c(b.getAttribute("data-ajax-begin"),["xhr"]).apply(this,arguments);a!==false&&k.show(i);return a},complete:function(){k.hide(i);c(b.getAttribute("data-ajax-complete"),["xhr","status"]).apply(this,arguments)},success:function(a,e,d){h(b,a,d.getResponseHeader("Content-Type")||"text/html");c(b.getAttribute("data-ajax-success"),["data","status","xhr"]).apply(this,arguments)},error:c(b.getAttribute("data-ajax-failure"),["xhr","status","error"])});e.data.push({name:"X-Requested-With",value:"XMLHttpRequest"});g=e.type.toUpperCase();if(!d(g)){e.type="POST";e.data.push({name:"X-HTTP-Method-Override",value:g})}a.ajax(e)}function i(c){var b=a(c).data(g);return!b||!b.validate||b.validate()}a(document).on("click","a[data-ajax=true]",function(a){a.preventDefault();e(this,{url:this.href,type:"GET",data:[]})});a(document).on("click","form[data-ajax=true] input[type=image]",function(c){var g=c.target.name,d=a(c.target),f=d.parents("form")[0],e=d.offset();a(f).data(b,[{name:g+".x",value:Math.round(c.pageX-e.left)},{name:g+".y",value:Math.round(c.pageY-e.top)}]);setTimeout(function(){a(f).removeData(b)},0)});a(document).on("click","form[data-ajax=true] :submit",function(c){var e=c.target.name,d=a(c.target).parents("form")[0];a(d).data(b,e?[{name:e,value:c.target.value}]:[]);setTimeout(function(){a(d).removeData(b)},0)});a(document).on("submit","form[data-ajax=true]",function(d){var c=a(this).data(b)||[];d.preventDefault();if(!i(this))return;e(this,{url:this.action,type:this.method||"GET",data:c.concat(a(this).serializeArray())})})})(jQuery); -------------------------------------------------------------------------------- /LinqToQuerystring.Demo/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = null; 3 | } 4 | 5 | 6 | 7 | 8 | 9 | Error 10 | 11 | 12 |
13 |

Error.

14 |

An error occurred while processing your request.

15 |
16 | 17 | -------------------------------------------------------------------------------- /LinqToQuerystring.Demo/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | @ViewBag.Title 7 | @Styles.Render("~/Content/css") 8 | @Scripts.Render("~/bundles/modernizr") 9 | 10 | 11 |
12 |
13 |
14 |

15 | Linq to Querystring

16 |
17 |
18 | 23 |
24 |
25 |
26 | @RenderBody() 27 | 28 | @Scripts.Render("~/bundles/jquery") 29 | @Scripts.Render("~/bundles/knockout") 30 | @Scripts.Render("~/bundles/odata") 31 | @RenderSection("scripts", required: false) 32 | 33 | 34 | -------------------------------------------------------------------------------- /LinqToQuerystring.Demo/Views/Web.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 |
7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 40 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /LinqToQuerystring.Demo/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "~/Views/Shared/_Layout.cshtml"; 3 | } -------------------------------------------------------------------------------- /LinqToQuerystring.Demo/Web.Debug.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 17 | 18 | 29 | 30 | -------------------------------------------------------------------------------- /LinqToQuerystring.Demo/Web.Release.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 17 | 18 | 19 | 30 | 31 | -------------------------------------------------------------------------------- /LinqToQuerystring.Demo/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beyond-code-github/LinqToQuerystring/f10c41a86eced0f2cee830f07e8fc71e35496345/LinqToQuerystring.Demo/favicon.ico -------------------------------------------------------------------------------- /LinqToQuerystring.Demo/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /LinqToQuerystring.EntityFramework/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /LinqToQuerystring.EntityFramework/Configuration.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.EntityFramework 2 | { 3 | using LinqToQuerystring.Utils; 4 | 5 | public static class Configuration 6 | { 7 | public static void Init() 8 | { 9 | if (!LinqToQuerystring.Configuration.CustomNodes.ContainsKey("DbQueryProvider")) 10 | { 11 | LinqToQuerystring.Configuration.CustomNodes.Add("DbQueryProvider", new CustomNodeMappings()); 12 | } 13 | 14 | var objectQueryNodes = LinqToQuerystring.Configuration.CustomNodes["DbQueryProvider"]; 15 | if (!objectQueryNodes.ContainsKey(LinqToQuerystringLexer.EXPAND)) 16 | { 17 | objectQueryNodes.Add( 18 | LinqToQuerystringLexer.EXPAND, (type, token, factory) => new ExpandNode(type, token, factory)); 19 | } 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /LinqToQuerystring.EntityFramework/ExpandNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.EntityFramework 2 | { 3 | using System; 4 | using System.Data.Entity; 5 | using System.Linq; 6 | using System.Linq.Expressions; 7 | 8 | using Antlr.Runtime; 9 | 10 | using LinqToQuerystring.TreeNodes; 11 | using LinqToQuerystring.TreeNodes.Base; 12 | 13 | public class ExpandNode : QueryModifier 14 | { 15 | public ExpandNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 16 | : base(inputType, payload, treeNodeFactory) 17 | { 18 | } 19 | 20 | public override IQueryable ModifyQuery(IQueryable query) 21 | { 22 | foreach (var child in this.ChildNodes) 23 | { 24 | var parameter = Expression.Parameter(this.inputType, "o"); 25 | var childExpression = child.BuildLinqExpression(query, query.Expression, parameter); 26 | 27 | var member = childExpression as MemberExpression; 28 | query = query.Include(member.Member.Name); 29 | } 30 | 31 | return query; 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /LinqToQuerystring.EntityFramework/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("LinqToQuerystring.EntityFramework")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("LinqToQuerystring.EntityFramework")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("8beb2ad7-d375-4cfc-bdf4-d7f9b0d6a1ee")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.1.1.0")] 36 | [assembly: AssemblyFileVersion("1.1.1.0")] 37 | -------------------------------------------------------------------------------- /LinqToQuerystring.EntityFramework/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /LinqToQuerystring.IntegrationTests.EntityFramework/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /LinqToQuerystring.IntegrationTests.EntityFramework/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("LinqToQuerystring.IntegrationTests.EntityFramework")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("LinqToQuerystring.IntegrationTests.EntityFramework")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("ef0c64e1-f0dc-420a-a8c2-f4621ac91ee2")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /LinqToQuerystring.IntegrationTests.EntityFramework/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /LinqToQuerystring.IntegrationTests.Mongo/ConcreteMongoClass.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.IntegrationTests.Mongo 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | 6 | using MongoDB.Bson; 7 | using MongoDB.Bson.Serialization.Attributes; 8 | 9 | public class ConcreteMongoClass 10 | { 11 | [BsonId] 12 | [BsonRepresentation(BsonType.String)] 13 | public string Id { get; set; } 14 | 15 | public string Name { get; set; } 16 | 17 | public DateTime Date { get; set; } 18 | 19 | public bool Complete { get; set; } 20 | 21 | public int Age { get; set; } 22 | 23 | public List StringCollection { get; set; } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /LinqToQuerystring.IntegrationTests.Mongo/MongoDocument.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.IntegrationTests.Mongo 2 | { 3 | using System; 4 | 5 | using MongoDB.Bson; 6 | using MongoDB.Bson.Serialization; 7 | using MongoDB.Bson.Serialization.Attributes; 8 | 9 | [Serializable] 10 | [BsonSerializer(typeof(MongoDocumentClassSerializer))] 11 | public class MongoDocument : BsonDocumentBackedClass 12 | { 13 | public MongoDocument() 14 | : base(new MongoDocumentClassSerializer()) 15 | { 16 | } 17 | 18 | public MongoDocument(BsonDocument backingDocument) 19 | : base(backingDocument, new MongoDocumentClassSerializer()) 20 | { 21 | } 22 | 23 | public MongoDocument(BsonDocument backingDocument, IBsonDocumentSerializer serializer) 24 | : base(backingDocument, serializer) 25 | { 26 | 27 | } 28 | 29 | [BsonId] 30 | public ObjectId Id { get; set; } 31 | 32 | public BsonValue this[string fieldname] 33 | { 34 | get 35 | { 36 | return this.BackingDocument[fieldname]; 37 | } 38 | 39 | set 40 | { 41 | this.BackingDocument[fieldname] = value; 42 | } 43 | } 44 | 45 | public static implicit operator BsonDocument(MongoDocument document) 46 | { 47 | return document.BackingDocument; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /LinqToQuerystring.IntegrationTests.Mongo/MongoDocumentClassSerializer.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.IntegrationTests.Mongo 2 | { 3 | using System; 4 | 5 | using MongoDB.Bson; 6 | using MongoDB.Bson.Serialization; 7 | using MongoDB.Bson.Serialization.IdGenerators; 8 | using MongoDB.Bson.Serialization.Serializers; 9 | 10 | public class MongoDocumentClassSerializer : BsonDocumentBackedClassSerializer, IBsonIdProvider 11 | { 12 | public MongoDocumentClassSerializer() 13 | { 14 | this.RegisterMember("Id", "_id", ObjectIdSerializer.Instance, typeof(ObjectId), null); 15 | } 16 | 17 | protected override MongoDocument CreateInstance(BsonDocument backingDocument) 18 | { 19 | return new MongoDocument(backingDocument, this); 20 | } 21 | 22 | public bool GetDocumentId(object document, out object id, out Type idNominalType, out IIdGenerator idGenerator) 23 | { 24 | idNominalType = typeof(ObjectId); 25 | idGenerator = ObjectIdGenerator.Instance; 26 | 27 | var mongoDocument = document as MongoDocument; 28 | if (mongoDocument == null) 29 | { 30 | id = null; 31 | return false; 32 | } 33 | 34 | id = mongoDocument.Id; 35 | return true; 36 | } 37 | 38 | public void SetDocumentId(object document, object id) 39 | { 40 | var mongoDocument = document as MongoDocument; 41 | if (mongoDocument != null) 42 | { 43 | mongoDocument.Id = (ObjectId)id; 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /LinqToQuerystring.IntegrationTests.Mongo/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("LinqToQuerystring.IntegrationTests.Mongo")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("LinqToQuerystring.IntegrationTests.Mongo")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("dd21eed0-3fb8-4bf5-9486-67fcfba1df43")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /LinqToQuerystring.IntegrationTests.Mongo/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /LinqToQuerystring.IntegrationTests.WebAPI/ContentNegotiationTests.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.IntegrationTests.WebApi 2 | { 3 | using System.Linq; 4 | using System.Net; 5 | using System.Net.Http; 6 | using System.Web.Http; 7 | using System.Web.Http.Tracing; 8 | 9 | using Machine.Specifications; 10 | 11 | using WebAPI.Testing; 12 | 13 | public abstract class ContentNegotiationTestsBase 14 | { 15 | protected static Browser browser; 16 | 17 | protected static HttpResponseMessage response; 18 | 19 | protected Establish context = () => 20 | { 21 | var config = new HttpConfiguration(); 22 | config.Services.Replace(typeof(ITraceWriter), new SimpleTracer()); 23 | config.Formatters.Add(new CsvMediaTypeFormatter()); 24 | 25 | config.Routes.MapHttpRoute( 26 | name: "DefaultApi", 27 | routeTemplate: "api/{controller}/{id}", 28 | defaults: new { id = RouteParameter.Optional } 29 | ); 30 | 31 | browser = new Browser(config); 32 | }; 33 | } 34 | 35 | public class AcceptsJson : ContentNegotiationTestsBase 36 | { 37 | private Because of = () => response = browser.Get( 38 | "/api/data/", 39 | (with) => 40 | { 41 | with.Header("Accept", "application/json"); 42 | with.HttpRequest(); 43 | }); 44 | 45 | private It should_return_200_ok = () => response.StatusCode.ShouldEqual(HttpStatusCode.OK); 46 | } 47 | 48 | public class AcceptsXml : ContentNegotiationTestsBase 49 | { 50 | private Because of = () => response = browser.Get( 51 | "/api/data/", 52 | (with) => 53 | { 54 | with.Header("Accept", "application/xml"); 55 | with.HttpRequest(); 56 | }); 57 | 58 | private It should_return_200_ok = () => response.StatusCode.ShouldEqual(HttpStatusCode.OK); 59 | 60 | private It should_return_xml = () => response.Content.Headers.GetValues("Content-Type").FirstOrDefault().ShouldStartWith("application/xml"); 61 | } 62 | 63 | public class Can_handle_media_type_mappings : ContentNegotiationTestsBase 64 | { 65 | private Because of = () => response = browser.Get( 66 | "/api/data?format=csv", 67 | (with) => 68 | { 69 | with.Header("Accept", "text/csv"); 70 | with.HttpRequest(); 71 | }); 72 | 73 | private It should_return_200_ok = () => response.StatusCode.ShouldEqual(HttpStatusCode.OK); 74 | 75 | private It should_return_xml = () => response.Content.Headers.GetValues("Content-Type").FirstOrDefault().ShouldStartWith("text/csv"); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /LinqToQuerystring.IntegrationTests.WebAPI/Controllers/DataClass.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.IntegrationTests.WebApi.Controllers 2 | { 3 | using System; 4 | 5 | [Serializable] 6 | public class DataClass 7 | { 8 | private readonly string name; 9 | 10 | private readonly int age; 11 | 12 | private readonly bool awesome; 13 | 14 | public string Name 15 | { 16 | get 17 | { 18 | return this.name; 19 | } 20 | } 21 | 22 | public int Age 23 | { 24 | get 25 | { 26 | return this.age; 27 | } 28 | } 29 | 30 | public bool Awesome 31 | { 32 | get 33 | { 34 | return this.awesome; 35 | } 36 | } 37 | 38 | public DataClass(string name, int age, bool awesome) 39 | { 40 | this.name = name; 41 | this.age = age; 42 | this.awesome = awesome; 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /LinqToQuerystring.IntegrationTests.WebAPI/Controllers/DataController.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.IntegrationTests.WebApi.Controllers 2 | { 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Web.Http; 6 | 7 | using LinqToQuerystring.WebApi; 8 | 9 | public class DataController : ApiController 10 | { 11 | [LinqToQueryable] 12 | public IQueryable Get() 13 | { 14 | return 15 | new List 16 | { 17 | new DataClass("Peter", 29, true), 18 | new DataClass("Kathryn", 26, false) 19 | }.AsQueryable(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /LinqToQuerystring.IntegrationTests.WebAPI/Controllers/NonGenericController.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.IntegrationTests.WebApi.Controllers 2 | { 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Web.Http; 6 | 7 | using LinqToQuerystring.WebApi; 8 | 9 | public class NonGenericController : ApiController 10 | { 11 | [LinqToQueryable] 12 | public IQueryable Get() 13 | { 14 | return 15 | new List 16 | { 17 | new DataClass("Peter", 29, true), 18 | new DataClass("Kathryn", 26, false) 19 | }.AsQueryable(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /LinqToQuerystring.IntegrationTests.WebAPI/CsvMediaTypeFormatter.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.IntegrationTests.WebApi 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.IO; 6 | using System.Linq; 7 | using System.Net.Http.Formatting; 8 | using System.Net.Http.Headers; 9 | 10 | public class CsvMediaTypeFormatter : BufferedMediaTypeFormatter 11 | { 12 | public CsvMediaTypeFormatter() 13 | { 14 | SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/csv")); 15 | MediaTypeMappings.Add(new QueryStringMapping("format", "csv", "text/csv")); 16 | } 17 | 18 | public override bool CanReadType(Type type) 19 | { 20 | return false; 21 | } 22 | 23 | public override bool CanWriteType(Type type) 24 | { 25 | return true; 26 | } 27 | 28 | public override void WriteToStream( 29 | Type type, 30 | object value, 31 | Stream writeStream, 32 | System.Net.Http.HttpContent content) 33 | { 34 | var itemType = type.GetGenericArguments()[0]; 35 | var stringWriter = new StringWriter(); 36 | 37 | stringWriter.WriteLine(string.Join(",", itemType.GetProperties().Select(x => x.Name))); 38 | 39 | foreach (var obj in (IEnumerable)value) 40 | { 41 | var vals = obj.GetType().GetProperties().Select(pi => new { Value = pi.GetValue(obj, null) }); 42 | var valueLine = string.Empty; 43 | 44 | foreach (var val in vals) 45 | { 46 | if (val.Value != null) 47 | { 48 | var _val = val.Value.ToString(); 49 | 50 | //Check if the value contans a comma and place it in quotes if so 51 | if (_val.Contains(",")) _val = string.Concat("\"", _val, "\""); 52 | 53 | //Replace any \r or \n special characters from a new line with a space 54 | if (_val.Contains("\r")) _val = _val.Replace("\r", " "); 55 | if (_val.Contains("\n")) _val = _val.Replace("\n", " "); 56 | 57 | valueLine = string.Concat(valueLine, _val, ","); 58 | } 59 | else 60 | { 61 | valueLine = string.Concat(string.Empty, ","); 62 | } 63 | } 64 | 65 | stringWriter.WriteLine(valueLine.TrimEnd(',')); 66 | } 67 | 68 | var streamWriter = new StreamWriter(writeStream); 69 | streamWriter.Write(stringWriter.ToString()); 70 | } 71 | 72 | public override void SetDefaultContentHeaders( 73 | Type type, 74 | HttpContentHeaders headers, 75 | MediaTypeHeaderValue mediaType) 76 | { 77 | base.SetDefaultContentHeaders(type, headers, mediaType); 78 | headers.ContentType = new MediaTypeHeaderValue("text/csv"); 79 | headers.ContentDisposition = new ContentDispositionHeaderValue("attachment"); 80 | headers.ContentDisposition.FileName = "fields.csv"; 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /LinqToQuerystring.IntegrationTests.WebAPI/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("LinqToQuerystring.IntegrationTests.WebAPI")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("LinqToQuerystring.IntegrationTests.WebAPI")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("02b2e2d8-1844-40f7-b579-39df5de58797")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /LinqToQuerystring.IntegrationTests.WebAPI/SimpleTracer.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.IntegrationTests.WebApi 2 | { 3 | using System; 4 | using System.Net.Http; 5 | using System.Web.Http.Tracing; 6 | 7 | public class SimpleTracer : ITraceWriter 8 | { 9 | public void Trace(HttpRequestMessage request, string category, TraceLevel level, 10 | Action traceAction) 11 | { 12 | var rec = new TraceRecord(request, category, level); 13 | traceAction(rec); 14 | WriteTrace(rec); 15 | } 16 | 17 | protected void WriteTrace(TraceRecord rec) 18 | { 19 | var message = string.Format("{0};{1};{2}", 20 | rec.Operator, rec.Operation, rec.Message); 21 | System.Diagnostics.Trace.WriteLine(message, rec.Category); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /LinqToQuerystring.IntegrationTests.WebAPI/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /LinqToQuerystring.Javascript/antlr3-cli-min.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2003-2008 Terence Parr. All rights reserved. 3 | Code licensed under the BSD License: 4 | http://www.antlr.org/license.html 5 | 6 | Some parts of the ANTLR class: 7 | Copyright (c) 2008, Yahoo! Inc. All rights reserved. 8 | Code licensed under the BSD License: 9 | http://developer.yahoo.net/yui/license.txt 10 | */ 11 | org.antlr.runtime.ANTLRFileStream=function(D,A){this.fileName=D;var C;if(typeof java!=="undefined"){C="loadFileUsingJava"}else{throw new Error("ANTLR File I/O is not supported in this JS implementation.")}var B=this[C](D,A);org.antlr.runtime.ANTLRFileStream.superclass.constructor.call(this,B)};org.antlr.lang.extend(org.antlr.runtime.ANTLRFileStream,org.antlr.runtime.ANTLRStringStream,{getSourceName:function(){return this.fileName},loadFileUsingJava:function(H,E){var G=new java.io.File(H),C=G.length(),B,D=new java.io.FileInputStream(G);if(E){B=new java.io.InputStreamReader(D,E)}else{B=new java.io.InputStreamReader(D)}var A,F=[];while((A=B.read())>=0){F.push(String.fromCharCode(A))}return F.join("")}}); -------------------------------------------------------------------------------- /LinqToQuerystring.Javascript/antlr3-cli.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2003-2008 Terence Parr. All rights reserved. 3 | Code licensed under the BSD License: 4 | http://www.antlr.org/license.html 5 | 6 | Some parts of the ANTLR class: 7 | Copyright (c) 2008, Yahoo! Inc. All rights reserved. 8 | Code licensed under the BSD License: 9 | http://developer.yahoo.net/yui/license.txt 10 | */ 11 | /** This is a char buffer stream that is loaded from a file 12 | * all at once when you construct the object. This looks very 13 | * much like an ANTLReader or ANTLRInputStream, but it's a special case 14 | * since we know the exact size of the object to load. We can avoid lots 15 | * of data copying. 16 | */ 17 | org.antlr.runtime.ANTLRFileStream = function(fileName, encoding) { 18 | this.fileName = fileName; 19 | 20 | // @todo need to add support for other JS interpreters that have file i/o 21 | // hooks (SpiderMonkey and WSH come to mind). 22 | var method; 23 | if (typeof java !== "undefined") { // rhino 24 | method = "loadFileUsingJava"; 25 | } else { 26 | throw new Error( 27 | "ANTLR File I/O is not supported in this JS implementation." 28 | ); 29 | } 30 | 31 | var data = this[method](fileName, encoding); 32 | org.antlr.runtime.ANTLRFileStream.superclass.constructor.call(this, data); 33 | }; 34 | 35 | org.antlr.lang.extend(org.antlr.runtime.ANTLRFileStream, 36 | org.antlr.runtime.ANTLRStringStream, 37 | { 38 | getSourceName: function() { 39 | return this.fileName; 40 | }, 41 | 42 | loadFileUsingJava: function(fileName, encoding) { 43 | var f = new java.io.File(fileName), 44 | size = f.length(), 45 | isr, 46 | fis = new java.io.FileInputStream(f); 47 | if (encoding) { 48 | isr = new java.io.InputStreamReader(fis, encoding); 49 | } else { 50 | isr = new java.io.InputStreamReader(fis); 51 | } 52 | 53 | /* Should use the ternary version of isr.read here, but can't figure 54 | * out how to create a Java char array from JS. . . 55 | * @todo 56 | */ 57 | var charCode, data=[]; 58 | while ((charCode = isr.read()) >= 0) { 59 | data.push(String.fromCharCode(charCode)); 60 | } 61 | return data.join(""); 62 | } 63 | }); 64 | -------------------------------------------------------------------------------- /LinqToQuerystring.Javascript/output/LinqToQuerystring.tokens: -------------------------------------------------------------------------------- 1 | OCTAL_ESC=54 2 | MAX=27 3 | EQUALS=18 4 | COUNT=26 5 | ORDERBY=36 6 | NOT=17 7 | INLINECOUNT=11 8 | AND=16 9 | SUM=29 10 | EXPAND=10 11 | T__60=60 12 | SPACE=14 13 | T__55=55 14 | T__56=56 15 | ENDSWITH=33 16 | T__57=57 17 | T__58=58 18 | ESC_SEQ=52 19 | IDENTIFIER=31 20 | T__59=59 21 | ALL=25 22 | LESSTHANOREQUAL=23 23 | DOUBLE=44 24 | SELECT=9 25 | GREATERTHANOREQUAL=21 26 | HEX_PAIR=49 27 | GREATERTHAN=20 28 | BYTE=46 29 | LESSTHAN=22 30 | GUID=45 31 | SUBSTRINGOF=34 32 | ASC=37 33 | DATETIME=41 34 | UNICODE_ESC=53 35 | BOOL=39 36 | HEX_DIGIT=51 37 | NOTEQUALS=19 38 | INT=6 39 | MIN=28 40 | DYNAMICIDENTIFIER=47 41 | SKIP=5 42 | ANY=24 43 | TOLOWER=35 44 | NEWLINE=50 45 | SINGLE=43 46 | ALLPAGES=12 47 | NONE=13 48 | AVERAGE=30 49 | OR=15 50 | STARTSWITH=32 51 | ASSIGN=48 52 | FILTER=8 53 | ALIAS=4 54 | DESC=38 55 | LONG=42 56 | TOP=7 57 | STRING=40 58 | '/'=59 59 | ':'=60 60 | '('=57 61 | ','=56 62 | ')'=58 63 | '&'=55 64 | -------------------------------------------------------------------------------- /LinqToQuerystring.Nancy/LinqToQuerystring.Nancy.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {60E15FF4-5729-4B80-B30A-E5BA395BD039} 8 | Library 9 | Properties 10 | LinqToQuerystring.Nancy 11 | LinqToQuerystring.Nancy 12 | v4.0 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | {7859c906-95d8-4322-aa44-bc854b065aee} 49 | LinqToQuerystring 50 | 51 | 52 | 53 | 60 | -------------------------------------------------------------------------------- /LinqToQuerystring.Nancy/LinqToQuerystring.Nancy.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1.1 5 | Roysvork 6 | Roysvork 7 | LinqToQuerystring.Nancy 8 | LinqToQuerystring.Nancy 9 | false 10 | Provides an extension method for LinqToQuerystring that facilitates use with NancyFX 11 | Pete Smith 2014 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /LinqToQuerystring.Nancy/NancyExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.Nancy 2 | { 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | 6 | public static class NancyExtensions 7 | { 8 | public static dynamic LinqToQuerystring(this IQueryable query, IDictionary queryDictionary, bool forceDynamicProperties = false, int maxPageSize = -1) 9 | { 10 | var genericType = query.GetType().GetGenericArguments()[0]; 11 | 12 | var joined = string.Join( 13 | "&", queryDictionary.Select(o => o.Key + "=" + o.Value)); 14 | var queryString = !string.IsNullOrEmpty(joined) ? "?" + joined : string.Empty; 15 | 16 | return query.LinqToQuerystring(genericType, queryString, forceDynamicProperties, maxPageSize); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /LinqToQuerystring.Nancy/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("LinqToQuerystring.Nancy")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("LinqToQuerystring.Nancy")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("6d81d64c-4940-4647-922f-ecbeb72199d6")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.*")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /LinqToQuerystring.WebApi.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.21005.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{F5C6F2FB-E3FC-4787-B637-FC4AE2F70050}" 7 | ProjectSection(SolutionItems) = preProject 8 | .nuget\NuGet.Config = .nuget\NuGet.Config 9 | .nuget\NuGet.exe = .nuget\NuGet.exe 10 | .nuget\NuGet.targets = .nuget\NuGet.targets 11 | EndProjectSection 12 | EndProject 13 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{2313C896-8F93-46A4-9A5A-B148146256F3}" 14 | EndProject 15 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LinqToQuerystring.WebApi", "LinqToQuerystring.WebApi\LinqToQuerystring.WebApi.csproj", "{AC211100-2F7A-46A9-B630-C2DF57F50895}" 16 | EndProject 17 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LinqToQuerystring.IntegrationTests.WebApi", "LinqToQuerystring.IntegrationTests.WebAPI\LinqToQuerystring.IntegrationTests.WebApi.csproj", "{D9657640-E56D-440C-9566-67EDF848A64A}" 18 | EndProject 19 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LinqToQuerystring", "LinqToQuerystring\LinqToQuerystring.csproj", "{7859C906-95D8-4322-AA44-BC854B065AEE}" 20 | EndProject 21 | Global 22 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 23 | Debug|Any CPU = Debug|Any CPU 24 | Release|Any CPU = Release|Any CPU 25 | EndGlobalSection 26 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 27 | {AC211100-2F7A-46A9-B630-C2DF57F50895}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 28 | {AC211100-2F7A-46A9-B630-C2DF57F50895}.Debug|Any CPU.Build.0 = Debug|Any CPU 29 | {AC211100-2F7A-46A9-B630-C2DF57F50895}.Release|Any CPU.ActiveCfg = Release|Any CPU 30 | {AC211100-2F7A-46A9-B630-C2DF57F50895}.Release|Any CPU.Build.0 = Release|Any CPU 31 | {D9657640-E56D-440C-9566-67EDF848A64A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 32 | {D9657640-E56D-440C-9566-67EDF848A64A}.Debug|Any CPU.Build.0 = Debug|Any CPU 33 | {D9657640-E56D-440C-9566-67EDF848A64A}.Release|Any CPU.ActiveCfg = Release|Any CPU 34 | {D9657640-E56D-440C-9566-67EDF848A64A}.Release|Any CPU.Build.0 = Release|Any CPU 35 | {7859C906-95D8-4322-AA44-BC854B065AEE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 36 | {7859C906-95D8-4322-AA44-BC854B065AEE}.Debug|Any CPU.Build.0 = Debug|Any CPU 37 | {7859C906-95D8-4322-AA44-BC854B065AEE}.Release|Any CPU.ActiveCfg = Release|Any CPU 38 | {7859C906-95D8-4322-AA44-BC854B065AEE}.Release|Any CPU.Build.0 = Release|Any CPU 39 | EndGlobalSection 40 | GlobalSection(SolutionProperties) = preSolution 41 | HideSolutionNode = FALSE 42 | EndGlobalSection 43 | GlobalSection(NestedProjects) = preSolution 44 | {D9657640-E56D-440C-9566-67EDF848A64A} = {2313C896-8F93-46A4-9A5A-B148146256F3} 45 | EndGlobalSection 46 | EndGlobal 47 | -------------------------------------------------------------------------------- /LinqToQuerystring.WebApi/LinqToQueryableAttribute.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.WebApi 2 | { 3 | using System.Linq; 4 | using System.Net; 5 | using System.Net.Http; 6 | using System.Net.Http.Formatting; 7 | using System.Web.Http.Filters; 8 | 9 | using ActionFilterAttribute = System.Web.Http.Filters.ActionFilterAttribute; 10 | 11 | public class LinqToQueryableAttribute : ActionFilterAttribute 12 | { 13 | private readonly bool forceDynamicProperties; 14 | 15 | private readonly int maxPageSize; 16 | 17 | public LinqToQueryableAttribute(bool forceDynamicProperties = false, int maxPageSize = -1) 18 | { 19 | this.forceDynamicProperties = forceDynamicProperties; 20 | this.maxPageSize = maxPageSize; 21 | } 22 | 23 | public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) 24 | { 25 | if (actionExecutedContext.Response != null) 26 | { 27 | object responseObject; 28 | 29 | actionExecutedContext.Response.TryGetContentValue(out responseObject); 30 | var originalquery = responseObject as IQueryable; 31 | 32 | if (originalquery != null) 33 | { 34 | var queryString = actionExecutedContext.Request.RequestUri.Query; 35 | var genericType = originalquery.GetType().GetGenericArguments()[0]; 36 | 37 | var reply = originalquery.LinqToQuerystring(genericType, queryString, this.forceDynamicProperties, this.maxPageSize); 38 | var replyType = reply.GetType(); 39 | 40 | if (typeof(IQueryable).IsAssignableFrom(replyType)) 41 | { 42 | var queryableType = typeof(IQueryable<>).GetGenericTypeDefinition(); 43 | var genericArgs = replyType.GetGenericArguments(); 44 | replyType = queryableType.MakeGenericType(genericArgs); 45 | } 46 | 47 | var configuraton = actionExecutedContext.ActionContext.ControllerContext.Configuration; 48 | var conneg = (IContentNegotiator) configuraton.Services.GetService(typeof(IContentNegotiator)); 49 | var formatter = conneg.Negotiate( 50 | replyType, 51 | actionExecutedContext.Request, 52 | configuraton.Formatters); 53 | 54 | actionExecutedContext.Response = new HttpResponseMessage 55 | { 56 | StatusCode = HttpStatusCode.OK, 57 | Content = new ObjectContent(replyType, reply, formatter.Formatter) 58 | }; 59 | } 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /LinqToQuerystring.WebApi/LinqToQuerystring.WebAPI.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 0.0 5 | Roysvork 6 | Roysvork 7 | LinqToQuerystring.WebApi 8 | Linq to Querystring - Web Api 9 | false 10 | Provides an action filter to enable LinqToQuerystring for Web API actions that return IQueryable 11 | Pete Smith 2013 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /LinqToQuerystring.WebApi/LinqToQuerystring.WebAPI2.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 0.0 5 | Roysvork 6 | Roysvork 7 | LinqToQuerystring.WebApi2 8 | Linq to Querystring - Web Api 2 9 | false 10 | Provides an action filter to enable LinqToQuerystring for Web API 2 actions that return IQueryable 11 | Pete Smith 2013 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /LinqToQuerystring.WebApi/LinqToQuerystring.WebApi.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {AC211100-2F7A-46A9-B630-C2DF57F50895} 8 | Library 9 | Properties 10 | LinqToQuerystring.WebApi 11 | LinqToQuerystring.WebApi 12 | v4.0 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | {7859c906-95d8-4322-aa44-bc854b065aee} 47 | LinqToQuerystring 48 | 49 | 50 | 51 | 58 | -------------------------------------------------------------------------------- /LinqToQuerystring.WebApi/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("LinqToQuerystring.WebApi")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("LinqToQuerystring.WebApi")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("945f67c2-ff20-42ab-ac59-ed9a9be21728")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.3.1.*")] 35 | [assembly: AssemblyFileVersion("1.3.1.0")] 36 | -------------------------------------------------------------------------------- /LinqToQuerystring.WebApi/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /LinqToQuerystring.WebApi2.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.21126.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{F5C6F2FB-E3FC-4787-B637-FC4AE2F70050}" 7 | ProjectSection(SolutionItems) = preProject 8 | .nuget\NuGet.Config = .nuget\NuGet.Config 9 | .nuget\NuGet.exe = .nuget\NuGet.exe 10 | .nuget\NuGet.targets = .nuget\NuGet.targets 11 | EndProjectSection 12 | EndProject 13 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{2313C896-8F93-46A4-9A5A-B148146256F3}" 14 | EndProject 15 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LinqToQuerystring.WebApi2", "LinqToQuerystring.WebApi\LinqToQuerystring.WebApi2.csproj", "{C2EBA6BA-11AD-4AF7-B935-B71B761A63FC}" 16 | EndProject 17 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LinqToQuerystring.IntegrationTests.WebApi2", "LinqToQuerystring.IntegrationTests.WebAPI\LinqToQuerystring.IntegrationTests.WebApi2.csproj", "{6892C887-A339-4F81-93F2-FFEF64DCE7BE}" 18 | EndProject 19 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LinqToQuerystring", "LinqToQuerystring\LinqToQuerystring.csproj", "{7859C906-95D8-4322-AA44-BC854B065AEE}" 20 | EndProject 21 | Global 22 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 23 | Debug|Any CPU = Debug|Any CPU 24 | Release|Any CPU = Release|Any CPU 25 | EndGlobalSection 26 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 27 | {C2EBA6BA-11AD-4AF7-B935-B71B761A63FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 28 | {C2EBA6BA-11AD-4AF7-B935-B71B761A63FC}.Debug|Any CPU.Build.0 = Debug|Any CPU 29 | {C2EBA6BA-11AD-4AF7-B935-B71B761A63FC}.Release|Any CPU.ActiveCfg = Release|Any CPU 30 | {C2EBA6BA-11AD-4AF7-B935-B71B761A63FC}.Release|Any CPU.Build.0 = Release|Any CPU 31 | {6892C887-A339-4F81-93F2-FFEF64DCE7BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 32 | {6892C887-A339-4F81-93F2-FFEF64DCE7BE}.Debug|Any CPU.Build.0 = Debug|Any CPU 33 | {6892C887-A339-4F81-93F2-FFEF64DCE7BE}.Release|Any CPU.ActiveCfg = Release|Any CPU 34 | {6892C887-A339-4F81-93F2-FFEF64DCE7BE}.Release|Any CPU.Build.0 = Release|Any CPU 35 | {7859C906-95D8-4322-AA44-BC854B065AEE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 36 | {7859C906-95D8-4322-AA44-BC854B065AEE}.Debug|Any CPU.Build.0 = Debug|Any CPU 37 | {7859C906-95D8-4322-AA44-BC854B065AEE}.Release|Any CPU.ActiveCfg = Release|Any CPU 38 | {7859C906-95D8-4322-AA44-BC854B065AEE}.Release|Any CPU.Build.0 = Release|Any CPU 39 | EndGlobalSection 40 | GlobalSection(SolutionProperties) = preSolution 41 | HideSolutionNode = FALSE 42 | EndGlobalSection 43 | GlobalSection(NestedProjects) = preSolution 44 | {6892C887-A339-4F81-93F2-FFEF64DCE7BE} = {2313C896-8F93-46A4-9A5A-B148146256F3} 45 | EndGlobalSection 46 | EndGlobal 47 | -------------------------------------------------------------------------------- /LinqToQuerystring/Configuration.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | 6 | using LinqToQuerystring.Utils; 7 | 8 | public static class Configuration 9 | { 10 | public static Func DefaultTypeMap = (type) => type; 11 | 12 | public static Func DefaultTypeConversionMap = (from, to) => to; 13 | 14 | /// 15 | /// Exstensibility point for specifying an alternate type mapping when casting to IEnumerable 16 | /// 17 | public static Func EnumerableTypeMap { get; set; } 18 | 19 | /// 20 | /// Exstensibility point for specifying an alternate type mapping when casting values 21 | /// 22 | public static Func TypeConversionMap { get; set; } 23 | 24 | /// 25 | /// Allows the specification of custom tree nodes for particular situations, i.e Entity Framework include 26 | /// 27 | public static Dictionary CustomNodes { get; set; } 28 | 29 | public static void Reset() 30 | { 31 | EnumerableTypeMap = DefaultTypeMap; 32 | TypeConversionMap = DefaultTypeConversionMap; 33 | CustomNodes = new Dictionary(); 34 | } 35 | 36 | static Configuration() 37 | { 38 | Reset(); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /LinqToQuerystring/Exceptions/FunctionNotSupportedException.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.Exceptions 2 | { 3 | using System; 4 | 5 | public class FunctionNotSupportedException : Exception 6 | { 7 | public FunctionNotSupportedException(Type type, string function) 8 | : base(string.Format("{0} does not support the '{1}' function.", type, function)) 9 | { 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /LinqToQuerystring/Exceptions/InvalidEscapeSequenceException.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.Exceptions 2 | { 3 | using System; 4 | 5 | public class InvalidEscapeSequenceException : Exception 6 | { 7 | public InvalidEscapeSequenceException(string text) 8 | : base(string.Format("Invalid escape sequence {0}", text)) 9 | { 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /LinqToQuerystring/LinqToQuerystring.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 0.0 5 | Roysvork 6 | Roysvork 7 | LinqToQuerystring 8 | Linq to Querystring 9 | false 10 | Linq to Querystring is an expression parser for .NET that aims to provide a lightweight subset of the OData URI Specification 11 | Pete Smith 2013 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /LinqToQuerystring/LinqToQuerystring.tokens: -------------------------------------------------------------------------------- 1 | T__70=70 2 | T__71=71 3 | T__72=72 4 | T__73=73 5 | T__74=74 6 | T__75=75 7 | ALIAS=4 8 | ALL=5 9 | ALLPAGES=6 10 | AND=7 11 | ANY=8 12 | ASC=9 13 | ASSIGN=10 14 | AVERAGE=11 15 | BOOL=12 16 | BYTE=13 17 | COUNT=14 18 | DATETIME=15 19 | DAY=16 20 | DAYS=17 21 | DECIMAL=18 22 | DESC=19 23 | DOUBLE=20 24 | DYNAMICIDENTIFIER=21 25 | ENDSWITH=22 26 | EQUALS=23 27 | ESC_SEQ=24 28 | EXPAND=25 29 | FILTER=26 30 | GREATERTHAN=27 31 | GREATERTHANOREQUAL=28 32 | GUID=29 33 | HEX_DIGIT=30 34 | HEX_PAIR=31 35 | HOUR=32 36 | HOURS=33 37 | IDENTIFIER=34 38 | IGNORED=35 39 | INLINECOUNT=36 40 | INT=37 41 | LESSTHAN=38 42 | LESSTHANOREQUAL=39 43 | LONG=40 44 | MAX=41 45 | MIN=42 46 | MINUTE=43 47 | MINUTES=44 48 | MONTH=45 49 | NEWLINE=46 50 | NONE=47 51 | NOT=48 52 | NOTEQUALS=49 53 | NULL=50 54 | OCTAL_ESC=51 55 | OR=52 56 | ORDERBY=53 57 | SECOND=54 58 | SECONDS=55 59 | SELECT=56 60 | SINGLE=57 61 | SKIP=58 62 | SPACE=59 63 | STARTSWITH=60 64 | STRING=61 65 | SUBSTRINGOF=62 66 | SUM=63 67 | TOLOWER=64 68 | TOP=65 69 | TOUPPER=66 70 | UNICODE_ESC=67 71 | YEAR=68 72 | YEARS=69 73 | '&'=70 74 | '('=71 75 | ')'=72 76 | ','=73 77 | '/'=74 78 | ':'=75 79 | -------------------------------------------------------------------------------- /LinqToQuerystring/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("LinqToQuerystring")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("LinqToQuerystring")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("10559342-1864-4ada-86f5-da27596111d4")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("0.6.5.*")] 35 | [assembly: AssemblyFileVersion("0.6.5.0")] 36 | -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/Aggregates/AllNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.Aggregates 2 | { 3 | using System; 4 | using System.Collections; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Linq.Expressions; 8 | 9 | using Antlr.Runtime; 10 | 11 | using LinqToQuerystring.TreeNodes.Base; 12 | 13 | public class AllNode : TreeNode 14 | { 15 | public AllNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 16 | : base(inputType, payload, treeNodeFactory) 17 | { 18 | } 19 | 20 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 21 | { 22 | var property = this.ChildNodes.ElementAt(0).BuildLinqExpression(query, expression, item); 23 | var alias = this.ChildNodes.ElementAt(1).Text; 24 | var filter = this.ChildNodes.ElementAt(2); 25 | 26 | var underlyingType = property.Type; 27 | if (typeof(IEnumerable).IsAssignableFrom(property.Type) && property.Type.GetGenericArguments().Any()) 28 | { 29 | underlyingType = property.Type.GetGenericArguments()[0]; 30 | } 31 | else 32 | { 33 | //We will sometimes need to cater for special cases here, such as Enumerating BsonValues 34 | underlyingType = Configuration.EnumerableTypeMap(underlyingType); 35 | var enumerable = typeof(IEnumerable<>).MakeGenericType(underlyingType); 36 | property = Expression.Convert(property, enumerable); 37 | } 38 | 39 | var parameter = Expression.Parameter(underlyingType, alias); 40 | 41 | var lambda = Expression.Lambda( 42 | filter.BuildLinqExpression(query, expression, parameter), new[] { parameter }); 43 | 44 | return Expression.Call(typeof(Enumerable), "All", new[] { underlyingType }, property, lambda); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/Aggregates/AnyNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.Aggregates 2 | { 3 | using System; 4 | using System.Collections; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Linq.Expressions; 8 | 9 | using Antlr.Runtime; 10 | 11 | using LinqToQuerystring.TreeNodes.Base; 12 | 13 | public class AnyNode : TreeNode 14 | { 15 | public AnyNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 16 | : base(inputType, payload, treeNodeFactory) 17 | { 18 | } 19 | 20 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 21 | { 22 | var property = this.ChildNodes.ElementAt(0).BuildLinqExpression(query, expression, item); 23 | var alias = this.ChildNodes.ElementAt(1).Text; 24 | var filter = this.ChildNodes.ElementAt(2); 25 | 26 | var underlyingType = property.Type; 27 | if (typeof(IEnumerable).IsAssignableFrom(property.Type) && property.Type.GetGenericArguments().Any()) 28 | { 29 | underlyingType = property.Type.GetGenericArguments()[0]; 30 | } 31 | else 32 | { 33 | //We will sometimes need to cater for special cases here, such as Enumerating BsonValues 34 | underlyingType = Configuration.EnumerableTypeMap(underlyingType); 35 | var enumerable = typeof(IEnumerable<>).MakeGenericType(underlyingType); 36 | property = Expression.Convert(property, enumerable); 37 | } 38 | 39 | var parameter = Expression.Parameter(underlyingType, alias); 40 | 41 | var lambda = Expression.Lambda( 42 | filter.BuildLinqExpression(query, expression, parameter), new[] { parameter }); 43 | 44 | return Expression.Call(typeof(Enumerable), "Any", new[] { underlyingType }, property, lambda); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/Aggregates/AverageNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.Aggregates 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.TreeNodes.Base; 10 | 11 | public class AverageNode : TreeNode 12 | { 13 | public AverageNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 14 | : base(inputType, payload, treeNodeFactory) 15 | { 16 | } 17 | 18 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 19 | { 20 | var property = this.ChildNodes.ElementAt(0).BuildLinqExpression(query, expression, item); 21 | return Expression.Call(typeof(Enumerable), "Average", null, property); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/Aggregates/CountNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.Aggregates 2 | { 3 | using System; 4 | using System.Collections; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Linq.Expressions; 8 | 9 | using Antlr.Runtime; 10 | 11 | using LinqToQuerystring.TreeNodes.Base; 12 | 13 | public class CountNode : TreeNode 14 | { 15 | public CountNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 16 | : base(inputType, payload, treeNodeFactory) 17 | { 18 | } 19 | 20 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 21 | { 22 | var property = this.ChildNodes.ElementAt(0).BuildLinqExpression(query, expression, item); 23 | 24 | var underlyingType = property.Type; 25 | if (typeof(IEnumerable).IsAssignableFrom(property.Type) && property.Type.GetGenericArguments().Any()) 26 | { 27 | underlyingType = property.Type.GetGenericArguments()[0]; 28 | } 29 | else 30 | { 31 | //We will sometimes need to cater for special cases here, such as Enumerating BsonValues 32 | underlyingType = Configuration.EnumerableTypeMap(underlyingType); 33 | var enumerable = typeof(IEnumerable<>).MakeGenericType(underlyingType); 34 | property = Expression.Convert(property, enumerable); 35 | } 36 | 37 | return Expression.Call(typeof(Enumerable), "Count", new[] { underlyingType }, property); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/Aggregates/MaxNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.Aggregates 2 | { 3 | using System; 4 | using System.Collections; 5 | using System.Linq; 6 | using System.Linq.Expressions; 7 | 8 | using Antlr.Runtime; 9 | 10 | using LinqToQuerystring.TreeNodes.Base; 11 | 12 | public class MaxNode : TreeNode 13 | { 14 | public MaxNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 15 | : base(inputType, payload, treeNodeFactory) 16 | { 17 | } 18 | 19 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 20 | { 21 | var property = this.ChildNodes.ElementAt(0).BuildLinqExpression(query, expression, item); 22 | 23 | var underlyingType = property.Type; 24 | if (typeof(IEnumerable).IsAssignableFrom(property.Type) && property.Type.GetGenericArguments().Any()) 25 | { 26 | underlyingType = property.Type.GetGenericArguments()[0]; 27 | } 28 | 29 | return Expression.Call(typeof(Enumerable), "Max", new[] { underlyingType }, property); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/Aggregates/MinNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.Aggregates 2 | { 3 | using System; 4 | using System.Collections; 5 | using System.Linq; 6 | using System.Linq.Expressions; 7 | 8 | using Antlr.Runtime; 9 | 10 | using LinqToQuerystring.TreeNodes.Base; 11 | 12 | public class MinNode : TreeNode 13 | { 14 | public MinNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 15 | : base(inputType, payload, treeNodeFactory) 16 | { 17 | } 18 | 19 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 20 | { 21 | var property = this.ChildNodes.ElementAt(0).BuildLinqExpression(query, expression, item); 22 | 23 | var underlyingType = property.Type; 24 | if (typeof(IEnumerable).IsAssignableFrom(property.Type) && property.Type.GetGenericArguments().Any()) 25 | { 26 | underlyingType = property.Type.GetGenericArguments()[0]; 27 | } 28 | 29 | return Expression.Call(typeof(Enumerable), "Min", new[] { underlyingType }, property); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/Aggregates/SumNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.Aggregates 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.TreeNodes.Base; 10 | 11 | public class SumNode : TreeNode 12 | { 13 | public SumNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 14 | : base(inputType, payload, treeNodeFactory) 15 | { 16 | } 17 | 18 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 19 | { 20 | var property = this.ChildNodes.ElementAt(0).BuildLinqExpression(query, expression, item); 21 | return Expression.Call(typeof(Enumerable), "Sum", null, property); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/AliasNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.TreeNodes.Base; 10 | 11 | public class AliasNode : TreeNode 12 | { 13 | public AliasNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 14 | : base(inputType, payload, treeNodeFactory) 15 | { 16 | } 17 | 18 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 19 | { 20 | var child = this.ChildNodes.FirstOrDefault(); 21 | if (child != null) 22 | { 23 | return child.BuildLinqExpression(query, expression, item); 24 | } 25 | 26 | return item; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/AndNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.TreeNodes.Base; 10 | 11 | public class AndNode : TwoChildNode 12 | { 13 | public AndNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 14 | : base(inputType, payload, treeNodeFactory) 15 | { 16 | } 17 | 18 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 19 | { 20 | return Expression.AndAlso( 21 | this.LeftNode.BuildLinqExpression(query, expression, item), 22 | this.RightNode.BuildLinqExpression(query, expression, item)); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/AscNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes 2 | { 3 | using System; 4 | using System.Diagnostics; 5 | using System.Linq; 6 | using System.Linq.Expressions; 7 | 8 | using Antlr.Runtime; 9 | 10 | using LinqToQuerystring.TreeNodes.Base; 11 | 12 | public class AscNode : ExplicitOrderByBase 13 | { 14 | public AscNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 15 | : base(inputType, payload, treeNodeFactory) 16 | { 17 | } 18 | 19 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 20 | { 21 | var parameter = item ?? Expression.Parameter(inputType, "o"); 22 | Expression childExpression = expression; 23 | 24 | var temp = parameter; 25 | foreach (var child in this.ChildNodes) 26 | { 27 | childExpression = child.BuildLinqExpression(query, childExpression, temp); 28 | temp = childExpression; 29 | } 30 | 31 | Debug.Assert(childExpression != null, "childExpression should never be null"); 32 | 33 | var methodName = "OrderBy"; 34 | if ((query.Provider.GetType().Name.Contains("DbQueryProvider") || query.Provider.GetType().Name.Contains("MongoQueryProvider")) && !this.IsFirstChild) 35 | { 36 | methodName = "ThenBy"; 37 | } 38 | 39 | var lambda = Expression.Lambda(childExpression, new[] { parameter as ParameterExpression }); 40 | return Expression.Call(typeof(Queryable), methodName, new[] { query.ElementType, childExpression.Type }, query.Expression, lambda); 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/Base/ExplicitOrderByBase.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.Base 2 | { 3 | using System; 4 | 5 | using Antlr.Runtime; 6 | 7 | public abstract class ExplicitOrderByBase : TreeNode 8 | { 9 | protected ExplicitOrderByBase(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 10 | : base(inputType, payload, treeNodeFactory) 11 | { 12 | this.IsFirstChild = false; 13 | } 14 | 15 | public bool IsFirstChild { get; set; } 16 | } 17 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/Base/QueryModifier.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace LinqToQuerystring.TreeNodes.Base 4 | { 5 | using System.Linq; 6 | 7 | using Antlr.Runtime; 8 | 9 | public abstract class QueryModifier : TreeNode 10 | { 11 | protected QueryModifier(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 12 | : base(inputType, payload, treeNodeFactory) 13 | { 14 | } 15 | 16 | public override System.Linq.Expressions.Expression BuildLinqExpression(System.Linq.IQueryable query, System.Linq.Expressions.Expression expression, System.Linq.Expressions.Expression item = null) 17 | { 18 | throw new NotSupportedException( 19 | string.Format("{0} is just a placeholder and should be handled differently in Extensions.cs", this.GetType().Name)); 20 | } 21 | 22 | public abstract IQueryable ModifyQuery(IQueryable query); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/Base/SingleChildNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.Base 2 | { 3 | using System; 4 | using System.Linq; 5 | 6 | using Antlr.Runtime; 7 | 8 | public abstract class SingleChildNode : TreeNode 9 | { 10 | protected SingleChildNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 11 | : base(inputType, payload, treeNodeFactory) 12 | { 13 | } 14 | 15 | public TreeNode ChildNode 16 | { 17 | get 18 | { 19 | var childNode = this.ChildNodes.FirstOrDefault(); 20 | if (childNode == null) 21 | { 22 | throw new InvalidOperationException(string.Format("No valid child for {0}", this.GetType())); 23 | } 24 | 25 | return childNode; 26 | } 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/Base/TwoChildNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.Base 2 | { 3 | using System; 4 | using System.Linq; 5 | 6 | using Antlr.Runtime; 7 | 8 | public abstract class TwoChildNode : TreeNode 9 | { 10 | protected TwoChildNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 11 | : base(inputType, payload, treeNodeFactory) 12 | { 13 | } 14 | 15 | public TreeNode LeftNode 16 | { 17 | get 18 | { 19 | var leftNode = this.ChildNodes.ElementAtOrDefault(0); 20 | if (leftNode == null) 21 | { 22 | throw new InvalidOperationException(string.Format("No valid left node for {0}", this.GetType())); 23 | } 24 | 25 | return leftNode; 26 | } 27 | } 28 | 29 | public TreeNode RightNode 30 | { 31 | get 32 | { 33 | var rightNode = this.ChildNodes.ElementAtOrDefault(1); 34 | if (rightNode == null) 35 | { 36 | throw new InvalidOperationException(string.Format("No valid right node for {0}", this.GetType())); 37 | } 38 | 39 | return rightNode; 40 | } 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/Comparisons/EqualsNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.Comparisons 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.TreeNodes.Base; 10 | 11 | public class EqualsNode : TwoChildNode 12 | { 13 | public EqualsNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 14 | : base(inputType, payload, treeNodeFactory) 15 | { 16 | } 17 | 18 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 19 | { 20 | var leftExpression = this.LeftNode.BuildLinqExpression(query, expression, item); 21 | var rightExpression = this.RightNode.BuildLinqExpression(query, expression, item); 22 | 23 | // Nasty workaround to avoid comparison of Aggregate functions to true or false which breaks Entity framework 24 | if (leftExpression.Type == typeof(bool) && rightExpression.Type == typeof(bool) && rightExpression is ConstantExpression) 25 | { 26 | if ((bool)(rightExpression as ConstantExpression).Value) 27 | { 28 | return leftExpression; 29 | } 30 | 31 | return Expression.Not(leftExpression); 32 | } 33 | 34 | if (rightExpression.Type == typeof(bool) && leftExpression.Type == typeof(bool) 35 | && leftExpression is ConstantExpression) 36 | { 37 | if ((bool)(leftExpression as ConstantExpression).Value) 38 | { 39 | return rightExpression; 40 | } 41 | 42 | return Expression.Not(rightExpression); 43 | } 44 | 45 | NormalizeTypes(ref leftExpression, ref rightExpression); 46 | 47 | return ApplyEnsuringNullablesHaveValues(Expression.Equal, leftExpression, rightExpression); 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/Comparisons/GreaterThanNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.Comparisons 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.TreeNodes.Base; 10 | 11 | public class GreaterThanNode : TwoChildNode 12 | { 13 | public GreaterThanNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 14 | : base(inputType, payload, treeNodeFactory) 15 | { 16 | } 17 | 18 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 19 | { 20 | var leftExpression = this.LeftNode.BuildLinqExpression(query, expression, item); 21 | var rightExpression = this.RightNode.BuildLinqExpression(query, expression, item); 22 | 23 | NormalizeTypes(ref leftExpression, ref rightExpression); 24 | 25 | return ApplyEnsuringNullablesHaveValues(Expression.GreaterThan, leftExpression, rightExpression); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/Comparisons/GreaterThanOrEqualNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.Comparisons 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.TreeNodes.Base; 10 | 11 | public class GreaterThanOrEqualNode : TwoChildNode 12 | { 13 | public GreaterThanOrEqualNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 14 | : base(inputType, payload, treeNodeFactory) 15 | { 16 | } 17 | 18 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 19 | { 20 | var leftExpression = this.LeftNode.BuildLinqExpression(query, expression, item); 21 | var rightExpression = this.RightNode.BuildLinqExpression(query, expression, item); 22 | 23 | NormalizeTypes(ref leftExpression, ref rightExpression); 24 | 25 | return ApplyEnsuringNullablesHaveValues(Expression.GreaterThanOrEqual, leftExpression, rightExpression); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/Comparisons/LessThanNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.Comparisons 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.TreeNodes.Base; 10 | 11 | public class LessThanNode : TwoChildNode 12 | { 13 | public LessThanNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 14 | : base(inputType, payload, treeNodeFactory) 15 | { 16 | } 17 | 18 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 19 | { 20 | var leftExpression = this.LeftNode.BuildLinqExpression(query, expression, item); 21 | var rightExpression = this.RightNode.BuildLinqExpression(query, expression, item); 22 | 23 | NormalizeTypes(ref leftExpression, ref rightExpression); 24 | 25 | return ApplyEnsuringNullablesHaveValues(Expression.LessThan, leftExpression, rightExpression); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/Comparisons/LessThanOrEqualNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.Comparisons 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.TreeNodes.Base; 10 | 11 | public class LessThanOrEqualNode : TwoChildNode 12 | { 13 | public LessThanOrEqualNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 14 | : base(inputType, payload, treeNodeFactory) 15 | { 16 | } 17 | 18 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 19 | { 20 | var leftExpression = this.LeftNode.BuildLinqExpression(query, expression, item); 21 | var rightExpression = this.RightNode.BuildLinqExpression(query, expression, item); 22 | 23 | NormalizeTypes(ref leftExpression, ref rightExpression); 24 | 25 | return ApplyEnsuringNullablesHaveValues(Expression.LessThanOrEqual, leftExpression, rightExpression); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/Comparisons/NotEqualsNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.Comparisons 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.TreeNodes.Base; 10 | 11 | public class NotEqualsNode : TwoChildNode 12 | { 13 | public NotEqualsNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 14 | : base(inputType, payload, treeNodeFactory) 15 | { 16 | } 17 | 18 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 19 | { 20 | var leftExpression = this.LeftNode.BuildLinqExpression(query, expression, item); 21 | var rightExpression = this.RightNode.BuildLinqExpression(query, expression, item); 22 | 23 | NormalizeTypes(ref leftExpression, ref rightExpression); 24 | 25 | return ApplyWithNullAsValidAlternative(Expression.NotEqual, leftExpression, rightExpression); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/DataTypes/BoolNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.DataTypes 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.TreeNodes.Base; 10 | 11 | public class BoolNode : TreeNode 12 | { 13 | public BoolNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 14 | : base(inputType, payload, treeNodeFactory) 15 | { 16 | } 17 | 18 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 19 | { 20 | return Expression.Constant(Convert.ToBoolean(this.Text)); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/DataTypes/ByteNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.DataTypes 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.TreeNodes.Base; 10 | 11 | public class ByteNode : TreeNode 12 | { 13 | public ByteNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 14 | : base(inputType, payload, treeNodeFactory) 15 | { 16 | } 17 | 18 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 19 | { 20 | return Expression.Constant(Convert.ToByte(this.Text.Replace("0x", string.Empty), 16)); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/DataTypes/DateTimeNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.DataTypes 2 | { 3 | using System; 4 | using System.Globalization; 5 | using System.Linq; 6 | using System.Linq.Expressions; 7 | 8 | using Antlr.Runtime; 9 | 10 | using LinqToQuerystring.TreeNodes.Base; 11 | 12 | public class DateTimeNode : TreeNode 13 | { 14 | public DateTimeNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 15 | : base(inputType, payload, treeNodeFactory) 16 | { 17 | } 18 | 19 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 20 | { 21 | var dateText = this.Text 22 | .Replace("datetime'", string.Empty) 23 | .Replace("'", string.Empty) 24 | .Replace(".", ":"); 25 | 26 | return Expression.Constant(DateTime.Parse(dateText, null, DateTimeStyles.RoundtripKind)); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/DataTypes/DecimalNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.DataTypes 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.TreeNodes.Base; 10 | 11 | public class DecimalNode : TreeNode 12 | { 13 | public DecimalNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 14 | : base(inputType, payload, treeNodeFactory) 15 | { 16 | } 17 | 18 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 19 | { 20 | return Expression.Constant(Convert.ToDecimal(this.Text.Replace("m", string.Empty))); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/DataTypes/DoubleNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.DataTypes 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.TreeNodes.Base; 10 | 11 | public class DoubleNode : TreeNode 12 | { 13 | public DoubleNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 14 | : base(inputType, payload, treeNodeFactory) 15 | { 16 | } 17 | 18 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 19 | { 20 | return Expression.Constant(Convert.ToDouble(this.Text.Replace("d",string.Empty))); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/DataTypes/GuidNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.DataTypes 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.TreeNodes.Base; 10 | 11 | public class GuidNode : TreeNode 12 | { 13 | public GuidNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 14 | : base(inputType, payload, treeNodeFactory) 15 | { 16 | } 17 | 18 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 19 | { 20 | var guidText = this.Text.Replace("guid'", string.Empty).Replace("'", string.Empty); 21 | return Expression.Constant(new Guid(guidText)); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/DataTypes/IntNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.DataTypes 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.TreeNodes.Base; 10 | 11 | public class IntNode : TreeNode 12 | { 13 | public IntNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 14 | : base(inputType, payload, treeNodeFactory) 15 | { 16 | } 17 | 18 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 19 | { 20 | return Expression.Constant(Convert.ToInt32(this.Text)); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/DataTypes/LongNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.DataTypes 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.TreeNodes.Base; 10 | 11 | public class LongNode : TreeNode 12 | { 13 | public LongNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 14 | : base(inputType, payload, treeNodeFactory) 15 | { 16 | } 17 | 18 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 19 | { 20 | return Expression.Constant(Convert.ToInt64(this.Text.Replace("L", string.Empty))); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/DataTypes/SingleNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.DataTypes 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.TreeNodes.Base; 10 | 11 | public class SingleNode : TreeNode 12 | { 13 | public SingleNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 14 | : base(inputType, payload, treeNodeFactory) 15 | { 16 | } 17 | 18 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 19 | { 20 | return Expression.Constant(Convert.ToSingle(this.Text.Replace("f", string.Empty))); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/DataTypes/StringNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.DataTypes 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.TreeNodes.Base; 10 | 11 | public class StringNode : TreeNode 12 | { 13 | public StringNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 14 | : base(inputType, payload, treeNodeFactory) 15 | { 16 | } 17 | 18 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 19 | { 20 | var text = this.Text.Trim('\''); 21 | text = text.Replace(@"\\", @"\"); 22 | text = text.Replace(@"\b", "\b"); 23 | text = text.Replace(@"\t", "\t"); 24 | text = text.Replace(@"\n", "\n"); 25 | text = text.Replace(@"\f", "\f"); 26 | text = text.Replace(@"\r", "\r"); 27 | text = text.Replace(@"\'", "'"); 28 | text = text.Replace(@"''", "'"); 29 | 30 | return Expression.Constant(text); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/DescNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes 2 | { 3 | using System; 4 | using System.Diagnostics; 5 | using System.Linq; 6 | using System.Linq.Expressions; 7 | 8 | using Antlr.Runtime; 9 | 10 | using LinqToQuerystring.TreeNodes.Base; 11 | 12 | public class DescNode : ExplicitOrderByBase 13 | { 14 | public DescNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 15 | : base(inputType, payload, treeNodeFactory) 16 | { 17 | } 18 | 19 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 20 | { 21 | var parameter = item ?? Expression.Parameter(inputType, "o"); 22 | Expression childExpression = expression; 23 | 24 | var temp = parameter; 25 | 26 | foreach (var child in this.ChildNodes.Cast()) 27 | { 28 | childExpression = child.BuildLinqExpression(query, childExpression, temp); 29 | temp = childExpression; 30 | } 31 | 32 | Debug.Assert(childExpression != null, "childExpression should never be null"); 33 | 34 | var methodName = "OrderByDescending"; 35 | if ((query.Provider.GetType().Name.Contains("DbQueryProvider") || query.Provider.GetType().Name.Contains("MongoQueryProvider")) && !this.IsFirstChild) 36 | { 37 | methodName = "ThenByDescending"; 38 | } 39 | 40 | var lambda = Expression.Lambda(childExpression, new[] { parameter as ParameterExpression }); 41 | return Expression.Call(typeof(Queryable), methodName, new[] { query.ElementType, childExpression.Type }, query.Expression, lambda); 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/DynamicIdentifierNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.TreeNodes.Base; 10 | 11 | public class DynamicIdentifierNode : TreeNode 12 | { 13 | public DynamicIdentifierNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 14 | : base(inputType, payload, treeNodeFactory) 15 | { 16 | } 17 | 18 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item) 19 | { 20 | var key = this.Text.Trim(new[] { '[', ']' }); 21 | var property = Expression.Call(item, "get_Item", null, Expression.Constant(key)); 22 | 23 | var child = this.ChildNodes.FirstOrDefault(); 24 | if (child != null) 25 | { 26 | return child.BuildLinqExpression(query, expression, property); 27 | } 28 | 29 | return property; 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/ExpandNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes 2 | { 3 | using System; 4 | using System.Linq; 5 | 6 | using Antlr.Runtime; 7 | 8 | using LinqToQuerystring.TreeNodes.Base; 9 | 10 | public class ExpandNode : QueryModifier 11 | { 12 | public ExpandNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 13 | : base(inputType, payload, treeNodeFactory) 14 | { 15 | } 16 | 17 | public override IQueryable ModifyQuery(IQueryable query) 18 | { 19 | throw new NotSupportedException("The Expand query option is not supported by this provder"); 20 | } 21 | 22 | public override int CompareTo(TreeNode other) 23 | { 24 | if (other is ExpandNode) 25 | { 26 | return 0; 27 | } 28 | 29 | return -1; 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/FilterNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.TreeNodes.Base; 10 | 11 | public class FilterNode : SingleChildNode 12 | { 13 | public FilterNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 14 | : base(inputType, payload, treeNodeFactory) 15 | { 16 | } 17 | 18 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 19 | { 20 | var parameter = item ?? Expression.Parameter(inputType, "o"); 21 | var lambda = Expression.Lambda( 22 | this.ChildNode.BuildLinqExpression(query, expression, parameter), new[] { parameter as ParameterExpression }); 23 | 24 | return Expression.Call(typeof(Queryable), "Where", new[] { query.ElementType }, query.Expression, lambda); 25 | } 26 | 27 | public override int CompareTo(TreeNode other) 28 | { 29 | if (other is FilterNode) 30 | { 31 | return 0; 32 | } 33 | 34 | return -1; 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/Functions/DayNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.Functions 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.Exceptions; 10 | using LinqToQuerystring.TreeNodes.Base; 11 | 12 | public class DayNode : SingleChildNode 13 | { 14 | public DayNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 15 | : base(inputType, payload, treeNodeFactory) 16 | { 17 | } 18 | 19 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 20 | { 21 | var childexpression = this.ChildNode.BuildLinqExpression(query, expression, item); 22 | 23 | if (!typeof(DateTime).IsAssignableFrom(childexpression.Type) && !typeof(DateTimeOffset).IsAssignableFrom(childexpression.Type)) 24 | { 25 | throw new FunctionNotSupportedException(childexpression.Type, "day"); 26 | } 27 | 28 | return Expression.Property(childexpression, "Day"); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/Functions/DaysNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.Functions 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.Exceptions; 10 | using LinqToQuerystring.TreeNodes.Base; 11 | 12 | public class DaysNode : SingleChildNode 13 | { 14 | public DaysNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 15 | : base(inputType, payload, treeNodeFactory) 16 | { 17 | } 18 | 19 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 20 | { 21 | var childexpression = this.ChildNode.BuildLinqExpression(query, expression, item); 22 | 23 | if (!typeof(DateTime).IsAssignableFrom(childexpression.Type)) 24 | { 25 | throw new FunctionNotSupportedException(childexpression.Type, "days"); 26 | } 27 | 28 | return Expression.Property(childexpression, "Day"); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/Functions/EndsWithNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.Functions 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.TreeNodes.Base; 10 | 11 | public class EndsWithNode : TwoChildNode 12 | { 13 | public EndsWithNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 14 | : base(inputType, payload, treeNodeFactory) 15 | { 16 | } 17 | 18 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 19 | { 20 | var leftExpression = this.LeftNode.BuildLinqExpression(query, expression, item); 21 | var rightExpression = this.RightNode.BuildLinqExpression(query, expression, item); 22 | 23 | if (!typeof(string).IsAssignableFrom(leftExpression.Type)) 24 | { 25 | leftExpression = Expression.Convert(leftExpression, typeof(string)); 26 | } 27 | 28 | if (!typeof(string).IsAssignableFrom(rightExpression.Type)) 29 | { 30 | rightExpression = Expression.Convert(rightExpression, typeof(string)); 31 | } 32 | 33 | return Expression.Call(leftExpression, "EndsWith", null, new[] { rightExpression }); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/Functions/HourNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.Functions 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.Exceptions; 10 | using LinqToQuerystring.TreeNodes.Base; 11 | 12 | public class HourNode : SingleChildNode 13 | { 14 | public HourNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 15 | : base(inputType, payload, treeNodeFactory) 16 | { 17 | } 18 | 19 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 20 | { 21 | var childexpression = this.ChildNode.BuildLinqExpression(query, expression, item); 22 | 23 | if (!typeof(DateTime).IsAssignableFrom(childexpression.Type) && !typeof(DateTimeOffset).IsAssignableFrom(childexpression.Type)) 24 | { 25 | throw new FunctionNotSupportedException(childexpression.Type, "hour"); 26 | } 27 | 28 | return Expression.Property(childexpression, "Hour"); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/Functions/HoursNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.Functions 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.Exceptions; 10 | using LinqToQuerystring.TreeNodes.Base; 11 | 12 | public class HoursNode : SingleChildNode 13 | { 14 | public HoursNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 15 | : base(inputType, payload, treeNodeFactory) 16 | { 17 | } 18 | 19 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 20 | { 21 | var childexpression = this.ChildNode.BuildLinqExpression(query, expression, item); 22 | 23 | if (!typeof(DateTime).IsAssignableFrom(childexpression.Type)) 24 | { 25 | throw new FunctionNotSupportedException(childexpression.Type, "hours"); 26 | } 27 | 28 | return Expression.Property(childexpression, "Hour"); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/Functions/MinuteNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.Functions 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.Exceptions; 10 | using LinqToQuerystring.TreeNodes.Base; 11 | 12 | public class MinuteNode : SingleChildNode 13 | { 14 | public MinuteNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 15 | : base(inputType, payload, treeNodeFactory) 16 | { 17 | } 18 | 19 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 20 | { 21 | var childexpression = this.ChildNode.BuildLinqExpression(query, expression, item); 22 | 23 | if (!typeof(DateTime).IsAssignableFrom(childexpression.Type) && !typeof(DateTimeOffset).IsAssignableFrom(childexpression.Type)) 24 | { 25 | throw new FunctionNotSupportedException(childexpression.Type, "minute"); 26 | } 27 | 28 | return Expression.Property(childexpression, "Minute"); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/Functions/MinutesNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.Functions 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.Exceptions; 10 | using LinqToQuerystring.TreeNodes.Base; 11 | 12 | public class MinutesNode : SingleChildNode 13 | { 14 | public MinutesNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 15 | : base(inputType, payload, treeNodeFactory) 16 | { 17 | } 18 | 19 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 20 | { 21 | var childexpression = this.ChildNode.BuildLinqExpression(query, expression, item); 22 | 23 | if (!typeof(DateTime).IsAssignableFrom(childexpression.Type)) 24 | { 25 | throw new FunctionNotSupportedException(childexpression.Type, "minutes"); 26 | } 27 | 28 | return Expression.Property(childexpression, "Minute"); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/Functions/MonthNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.Functions 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.Exceptions; 10 | using LinqToQuerystring.TreeNodes.Base; 11 | 12 | public class MonthNode : SingleChildNode 13 | { 14 | public MonthNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 15 | : base(inputType, payload, treeNodeFactory) 16 | { 17 | } 18 | 19 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 20 | { 21 | var childexpression = this.ChildNode.BuildLinqExpression(query, expression, item); 22 | 23 | if (!typeof(DateTime).IsAssignableFrom(childexpression.Type)) 24 | { 25 | throw new FunctionNotSupportedException(childexpression.Type, "month"); 26 | } 27 | 28 | return Expression.Property(childexpression, "Month"); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/Functions/SecondNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.Functions 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.Exceptions; 10 | using LinqToQuerystring.TreeNodes.Base; 11 | 12 | public class SecondNode : SingleChildNode 13 | { 14 | public SecondNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 15 | : base(inputType, payload, treeNodeFactory) 16 | { 17 | } 18 | 19 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 20 | { 21 | var childexpression = this.ChildNode.BuildLinqExpression(query, expression, item); 22 | 23 | if (!typeof(DateTime).IsAssignableFrom(childexpression.Type) && !typeof(DateTimeOffset).IsAssignableFrom(childexpression.Type)) 24 | { 25 | throw new FunctionNotSupportedException(childexpression.Type, "second"); 26 | } 27 | 28 | return Expression.Property(childexpression, "Second"); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/Functions/SecondsNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.Functions 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.Exceptions; 10 | using LinqToQuerystring.TreeNodes.Base; 11 | 12 | public class SecondsNode : SingleChildNode 13 | { 14 | public SecondsNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 15 | : base(inputType, payload, treeNodeFactory) 16 | { 17 | } 18 | 19 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 20 | { 21 | var childexpression = this.ChildNode.BuildLinqExpression(query, expression, item); 22 | 23 | if (!typeof(DateTime).IsAssignableFrom(childexpression.Type)) 24 | { 25 | throw new FunctionNotSupportedException(childexpression.Type, "seconds"); 26 | } 27 | 28 | return Expression.Property(childexpression, "Second"); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/Functions/StartsWithNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.Functions 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.TreeNodes.Base; 10 | 11 | public class StartsWithNode : TwoChildNode 12 | { 13 | public StartsWithNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 14 | : base(inputType, payload, treeNodeFactory) 15 | { 16 | } 17 | 18 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 19 | { 20 | var leftExpression = this.LeftNode.BuildLinqExpression(query, expression, item); 21 | var rightExpression = this.RightNode.BuildLinqExpression(query, expression, item); 22 | 23 | if (!typeof(string).IsAssignableFrom(leftExpression.Type)) 24 | { 25 | leftExpression = Expression.Convert(leftExpression, typeof(string)); 26 | } 27 | 28 | if (!typeof(string).IsAssignableFrom(rightExpression.Type)) 29 | { 30 | rightExpression = Expression.Convert(rightExpression, typeof(string)); 31 | } 32 | 33 | return Expression.Call(leftExpression, "StartsWith", null, new[] { rightExpression }); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/Functions/SubstringOfNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.Functions 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.TreeNodes.Base; 10 | 11 | public class SubstringOfNode : TwoChildNode 12 | { 13 | public SubstringOfNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 14 | : base(inputType, payload, treeNodeFactory) 15 | { 16 | } 17 | 18 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 19 | { 20 | var leftExpression = this.LeftNode.BuildLinqExpression(query, expression, item); 21 | var rightExpression = this.RightNode.BuildLinqExpression(query, expression, item); 22 | 23 | if (!typeof(string).IsAssignableFrom(leftExpression.Type)) 24 | { 25 | leftExpression = Expression.Convert(leftExpression, typeof(string)); 26 | } 27 | 28 | if (!typeof(string).IsAssignableFrom(rightExpression.Type)) 29 | { 30 | rightExpression = Expression.Convert(rightExpression, typeof(string)); 31 | } 32 | 33 | return Expression.Call(rightExpression, "Contains", null, new[] { leftExpression }); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/Functions/ToLowerNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.Functions 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.TreeNodes.Base; 10 | 11 | public class ToLowerNode : SingleChildNode 12 | { 13 | public ToLowerNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 14 | : base(inputType, payload, treeNodeFactory) 15 | { 16 | } 17 | 18 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 19 | { 20 | var childexpression = this.ChildNode.BuildLinqExpression(query, expression, item); 21 | 22 | if (!typeof(string).IsAssignableFrom(childexpression.Type)) 23 | { 24 | childexpression = Expression.Convert(childexpression, typeof(string)); 25 | } 26 | 27 | return Expression.Call(childexpression, "ToLower", null, null); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/Functions/ToUpperNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.Functions 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.TreeNodes.Base; 10 | 11 | public class ToUpperNode : SingleChildNode 12 | { 13 | public ToUpperNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 14 | : base(inputType, payload, treeNodeFactory) 15 | { 16 | } 17 | 18 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 19 | { 20 | var childexpression = this.ChildNode.BuildLinqExpression(query, expression, item); 21 | 22 | if (!typeof(string).IsAssignableFrom(childexpression.Type)) 23 | { 24 | childexpression = Expression.Convert(childexpression, typeof(string)); 25 | } 26 | 27 | return Expression.Call(childexpression, "ToUpper", null, null); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/Functions/YearNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.Functions 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.Exceptions; 10 | using LinqToQuerystring.TreeNodes.Base; 11 | 12 | public class YearNode : SingleChildNode 13 | { 14 | public YearNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 15 | : base(inputType, payload, treeNodeFactory) 16 | { 17 | } 18 | 19 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 20 | { 21 | var childexpression = this.ChildNode.BuildLinqExpression(query, expression, item); 22 | 23 | if (!typeof(DateTime).IsAssignableFrom(childexpression.Type) && !typeof(DateTimeOffset).IsAssignableFrom(childexpression.Type)) 24 | { 25 | throw new FunctionNotSupportedException(childexpression.Type, "year"); 26 | } 27 | 28 | return Expression.Property(childexpression, "Year"); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/Functions/YearsNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.Functions 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.Exceptions; 10 | using LinqToQuerystring.TreeNodes.Base; 11 | 12 | public class YearsNode : SingleChildNode 13 | { 14 | public YearsNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 15 | : base(inputType, payload, treeNodeFactory) 16 | { 17 | } 18 | 19 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 20 | { 21 | var childexpression = this.ChildNode.BuildLinqExpression(query, expression, item); 22 | 23 | if (!typeof(DateTime).IsAssignableFrom(childexpression.Type)) 24 | { 25 | throw new FunctionNotSupportedException(childexpression.Type, "years"); 26 | } 27 | 28 | return Expression.Property(childexpression, "Year"); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/IdentifierNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.TreeNodes.Base; 10 | 11 | public class IdentifierNode : TreeNode 12 | { 13 | public IdentifierNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 14 | : base(inputType, payload, treeNodeFactory) 15 | { 16 | } 17 | 18 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item) 19 | { 20 | var property = Expression.Property(item, this.Text); 21 | 22 | var child = this.ChildNodes.FirstOrDefault(); 23 | if (child != null) 24 | { 25 | return child.BuildLinqExpression(query, expression, property); 26 | } 27 | 28 | return property; 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/IgnoredNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.TreeNodes.Base; 10 | 11 | public class IgnoredNode : TreeNode 12 | { 13 | public IgnoredNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 14 | : base(inputType, payload, treeNodeFactory) 15 | { 16 | } 17 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 18 | { 19 | return expression; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/InlineCountNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.TreeNodes.Base; 10 | 11 | public class InlineCountNode : SingleChildNode 12 | { 13 | public InlineCountNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 14 | : base(inputType, payload, treeNodeFactory) 15 | { 16 | } 17 | 18 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 19 | { 20 | throw new NotSupportedException( 21 | "InlineCountNode is just a placeholder and should be handled differently in Extensions.cs"); 22 | } 23 | 24 | public override int CompareTo(TreeNode other) 25 | { 26 | if (other is InlineCountNode) 27 | { 28 | return 0; 29 | } 30 | 31 | return 1; 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/NotNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.TreeNodes.Base; 10 | 11 | public class NotNode : SingleChildNode 12 | { 13 | public NotNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 14 | : base(inputType, payload, treeNodeFactory) 15 | { 16 | } 17 | 18 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 19 | { 20 | var childExpression = this.ChildNode.BuildLinqExpression(query, expression, item); 21 | if (!typeof(bool).IsAssignableFrom(childExpression.Type)) 22 | { 23 | childExpression = Expression.Convert(childExpression, typeof(bool)); 24 | } 25 | 26 | return Expression.Not(childExpression); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/NullNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes.DataTypes 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.TreeNodes.Base; 10 | 11 | public class NullNode : TreeNode 12 | { 13 | public NullNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 14 | : base(inputType, payload, treeNodeFactory) 15 | { 16 | } 17 | 18 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 19 | { 20 | return Expression.Constant(null); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/OrNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.TreeNodes.Base; 10 | 11 | public class OrNode : TwoChildNode 12 | { 13 | public OrNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 14 | : base(inputType, payload, treeNodeFactory) 15 | { 16 | } 17 | 18 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 19 | { 20 | return Expression.OrElse( 21 | this.LeftNode.BuildLinqExpression(query, expression, item), 22 | this.RightNode.BuildLinqExpression(query, expression, item)); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/OrderByNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Linq.Expressions; 7 | 8 | using Antlr.Runtime; 9 | 10 | using LinqToQuerystring.TreeNodes.Base; 11 | 12 | public class OrderByNode : QueryModifier 13 | { 14 | public OrderByNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 15 | : base(inputType, payload, treeNodeFactory) 16 | { 17 | } 18 | 19 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 20 | { 21 | throw new NotSupportedException( 22 | "Orderby is just a placeholder and should be handled differently in Extensions.cs"); 23 | } 24 | 25 | public override IQueryable ModifyQuery(IQueryable query) 26 | { 27 | var queryresult = query; 28 | var orderbyChildren = this.Children.Cast(); 29 | 30 | if (!queryresult.Provider.GetType().Name.Contains("DbQueryProvider") && !queryresult.Provider.GetType().Name.Contains("MongoQueryProvider")) 31 | { 32 | orderbyChildren = orderbyChildren.Reverse(); 33 | } 34 | 35 | var explicitOrderByNodes = orderbyChildren as IList ?? orderbyChildren.ToList(); 36 | explicitOrderByNodes.First().IsFirstChild = true; 37 | 38 | foreach (var child in explicitOrderByNodes) 39 | { 40 | queryresult = queryresult.Provider.CreateQuery(child.BuildLinqExpression(queryresult, queryresult.Expression)); 41 | } 42 | 43 | return queryresult; 44 | } 45 | 46 | public override int CompareTo(TreeNode other) 47 | { 48 | if (other is OrderByNode) 49 | { 50 | return 0; 51 | } 52 | 53 | if (other is FilterNode || other is ExpandNode) 54 | { 55 | return 1; 56 | } 57 | 58 | return -1; 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/SelectNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Linq.Expressions; 7 | using System.Reflection; 8 | 9 | using Antlr.Runtime; 10 | 11 | using LinqToQuerystring.TreeNodes.Base; 12 | 13 | public class SelectNode : SingleChildNode 14 | { 15 | public SelectNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 16 | : base(inputType, payload, treeNodeFactory) 17 | { 18 | } 19 | 20 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 21 | { 22 | var fixedexpr = Expression.Call(typeof(Queryable), "Cast", new[] { inputType }, query.Expression); 23 | 24 | query = query.Provider.CreateQuery(fixedexpr); 25 | 26 | var parameter = item ?? Expression.Parameter(inputType, "o"); 27 | Expression childExpression = fixedexpr; 28 | 29 | MethodInfo addMethod = typeof(Dictionary).GetMethod("Add"); 30 | var elements = this.ChildNodes.Select( 31 | o => Expression.ElementInit(addMethod, Expression.Constant(o.Text), Expression.Convert(o.BuildLinqExpression(query, childExpression, parameter), typeof(object)))); 32 | 33 | var newDictionary = Expression.New(typeof(Dictionary)); 34 | var init = Expression.ListInit(newDictionary, elements); 35 | 36 | var lambda = Expression.Lambda(init, new[] { parameter as ParameterExpression }); 37 | return Expression.Call(typeof(Queryable), "Select", new[] { query.ElementType, typeof(Dictionary) }, query.Expression, lambda); 38 | } 39 | 40 | public override int CompareTo(TreeNode other) 41 | { 42 | if (other is SelectNode) 43 | { 44 | return 0; 45 | } 46 | 47 | // Select clause should always be last apart from inlinecount 48 | if (other is InlineCountNode) 49 | { 50 | return -1; 51 | } 52 | 53 | return 1; 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/SkipNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.TreeNodes.Base; 10 | 11 | public class SkipNode : SingleChildNode 12 | { 13 | public SkipNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 14 | : base(inputType, payload, treeNodeFactory) 15 | { 16 | } 17 | 18 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 19 | { 20 | return Expression.Call(typeof(Queryable), "Skip", new[] { query.ElementType }, query.Expression, this.ChildNode.BuildLinqExpression(query, expression)); 21 | } 22 | 23 | public override int CompareTo(TreeNode other) 24 | { 25 | if (other is SkipNode) 26 | { 27 | return 0; 28 | } 29 | 30 | if (other is OrderByNode || other is FilterNode) 31 | { 32 | return 1; 33 | } 34 | 35 | return -1; 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /LinqToQuerystring/TreeNodes/TopNode.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.TreeNodes 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.TreeNodes.Base; 10 | 11 | public class TopNode : SingleChildNode 12 | { 13 | public TopNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) 14 | : base(inputType, payload, treeNodeFactory) 15 | { 16 | } 17 | 18 | public override Expression BuildLinqExpression(IQueryable query, Expression expression, Expression item = null) 19 | { 20 | return Expression.Call( 21 | typeof(Queryable), 22 | "Take", 23 | new[] { query.ElementType }, 24 | query.Expression, 25 | this.ChildNode.BuildLinqExpression(query, expression)); 26 | } 27 | 28 | public override int CompareTo(TreeNode other) 29 | { 30 | if (other is TopNode) 31 | { 32 | return 0; 33 | } 34 | 35 | if (other is OrderByNode || other is FilterNode || other is SkipNode) 36 | { 37 | return 1; 38 | } 39 | 40 | return -1; 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /LinqToQuerystring/Utils/CustomNodeMappings.cs: -------------------------------------------------------------------------------- 1 | namespace LinqToQuerystring.Utils 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq.Expressions; 6 | 7 | using Antlr.Runtime; 8 | 9 | using LinqToQuerystring.TreeNodes; 10 | using LinqToQuerystring.TreeNodes.Base; 11 | 12 | public class CustomNodeMappings : Dictionary> 13 | { 14 | public TreeNode MapNode(TreeNode node, Expression expression) 15 | { 16 | if (this.ContainsKey(node.Type)) 17 | { 18 | var mappedNode = this[node.Type](node.inputType, node.payload, node.factory); 19 | mappedNode.AddChildren(node.Children); 20 | return mappedNode; 21 | } 22 | 23 | return node; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /LinqToQuerystring/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Linq to Querystring v0.7.0 2 | ========================== 3 | 4 | ## New Website 5 | Linq to Querystring now has a project page! Please refer to http://beyond-code.com/LinqToQuerystring/ for documentation and samples. 6 | 7 | ## Installation 8 | 9 | * Nuget package: https://nuget.org/packages/LinqToQuerystring/ 10 | PM> Install-Package LinqToQuerystring 11 | 12 | * Entity Framework package ($expand support): https://nuget.org/packages/LinqToQuerystring.EntityFramework/ 13 | PM> Install-Package LinqToQuerystring.EntityFramework 14 | 15 | * Web Api package: https://nuget.org/packages/LinqToQuerystring.WebApi/ 16 | PM> Install-Package LinqToQuerystring.WebApi 17 | 18 | * Web Api 2 package: https://nuget.org/packages/LinqToQuerystring.WebApi2/ 19 | PM> Install-Package LinqToQuerystring.WebApi2 20 | 21 | * Nancy FX package: https://nuget.org/packages/LinqToQuerystring.Nancy/ 22 | PM> Install-Package LinqToQuerystring.Nancy 23 | 24 | 25 | ###Contributors 26 | 27 | https://github.com/xt0rted 28 | -------------------------------------------------------------------------------- /lib/ANTLR/Antlr3.Runtime.Debug.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beyond-code-github/LinqToQuerystring/f10c41a86eced0f2cee830f07e8fc71e35496345/lib/ANTLR/Antlr3.Runtime.Debug.dll -------------------------------------------------------------------------------- /lib/ANTLR/Antlr3.Runtime.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beyond-code-github/LinqToQuerystring/f10c41a86eced0f2cee830f07e8fc71e35496345/lib/ANTLR/Antlr3.Runtime.dll -------------------------------------------------------------------------------- /lib/ANTLR/Antlr3.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beyond-code-github/LinqToQuerystring/f10c41a86eced0f2cee830f07e8fc71e35496345/lib/ANTLR/Antlr3.exe -------------------------------------------------------------------------------- /lib/ANTLR/Antlr3.exe.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /lib/ANTLR/Antlr4.StringTemplate.Visualizer.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beyond-code-github/LinqToQuerystring/f10c41a86eced0f2cee830f07e8fc71e35496345/lib/ANTLR/Antlr4.StringTemplate.Visualizer.dll -------------------------------------------------------------------------------- /lib/ANTLR/Antlr4.StringTemplate.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beyond-code-github/LinqToQuerystring/f10c41a86eced0f2cee830f07e8fc71e35496345/lib/ANTLR/Antlr4.StringTemplate.dll -------------------------------------------------------------------------------- /lib/ANTLR/AntlrBuildTask.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beyond-code-github/LinqToQuerystring/f10c41a86eced0f2cee830f07e8fc71e35496345/lib/ANTLR/AntlrBuildTask.dll -------------------------------------------------------------------------------- /lib/ANTLR/Codegen/Templates/CSharp3/ASTDbg.stg: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2005-2008 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Conversion to C#: 7 | * Copyright (c) 2008-2009 Sam Harwell, Pixel Mine, Inc. 8 | * All rights reserved. 9 | * 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions 12 | * are met: 13 | * 1. Redistributions of source code must retain the above copyright 14 | * notice, this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in the 17 | * documentation and/or other materials provided with the distribution. 18 | * 3. The name of the author may not be used to endorse or promote products 19 | * derived from this software without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | */ 32 | 33 | /** Template overrides to add debugging to AST stuff. Dynamic inheritance 34 | * hierarchy is set up as ASTDbg : AST : Dbg : Java by code generator. 35 | */ 36 | 37 | parserMembers() ::= << 38 | // Implement this function in your helper file to use a custom tree adaptor 39 | partial void InitializeTreeAdaptor(); 40 | protected DebugTreeAdaptor adaptor; 41 | 42 | public ITreeAdaptor TreeAdaptor 43 | { 44 | get 45 | { 46 | return adaptor; 47 | } 48 | set 49 | { 50 | 51 | this.adaptor = new DebugTreeAdaptor(dbg,adaptor); 52 | 53 | this.adaptor = (DebugTreeAdaptor)adaptor; // delegator sends dbg adaptor 54 | <\n> 55 | .TreeAdaptor = this.adaptor;}> 56 | } 57 | }<\n> 58 | >> 59 | 60 | parserCtorBody() ::= << 61 | 62 | >> 63 | 64 | createListenerAndHandshake() ::= << 65 | DebugEventSocketProxy proxy = new DebugEventSocketProxy( this, port, input.TreeAdaptoradaptor ); 66 | DebugListener = proxy; 67 | = new Debug( input, proxy ); 68 | try 69 | { 70 | proxy.Handshake(); 71 | } 72 | catch ( IOException ioe ) 73 | { 74 | ReportError( ioe ); 75 | } 76 | >> 77 | 78 | @ctorForRootGrammar.finally() ::= << 79 | ITreeAdaptor adap = new CommonTreeAdaptor(); 80 | TreeAdaptor = adap; 81 | proxy.TreeAdaptor = adap; 82 | >> 83 | 84 | @ctorForProfilingRootGrammar.finally() ::=<< 85 | ITreeAdaptor adap = new CommonTreeAdaptor(); 86 | TreeAdaptor = adap; 87 | >> 88 | 89 | @ctorForPredefinedListener.superClassRef() ::= ": base( input, dbg )" 90 | 91 | @ctorForPredefinedListener.finally() ::=<< 92 | 93 | ITreeAdaptor adap = new CommonTreeAdaptor(); 94 | TreeAdaptor = adap;<\n> 95 | 96 | >> 97 | 98 | //@rewriteElement.pregen() ::= "dbg.Location( , );" 99 | -------------------------------------------------------------------------------- /lib/ANTLR/Codegen/Templates/LeftRecursiveRules.stg: -------------------------------------------------------------------------------- 1 | /* 2 | [The "BSD license"] 3 | Copyright (c) 2010 Terence Parr 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions 8 | are met: 9 | 1. Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | 2. Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | 3. The name of the author may not be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /** How to generate rules derived from left-recursive rules. 30 | * These rely on recRuleDefArg(), recRuleAltPredicate(), 31 | * recRuleArg(), recRuleSetResultAction(), recRuleSetReturnAction() 32 | * templates in main language.stg 33 | */ 34 | group LeftRecursiveRules; 35 | 36 | recRuleName(ruleName) ::= "_" 37 | recPrimaryName(ruleName) ::= "_primary" 38 | 39 | recRuleStart(ruleName, minPrec, userRetvals, userRetvalAssignments) ::= << 40 | returns [] 41 | : [] 42 | 43 | { 44 | 45 | } 46 | 47 | ; 48 | >> 49 | 50 | recRule(ruleName, precArgDef, argName, alts, setResultAction, buildAST, 51 | userRetvals, userRetvalAssignments) ::= << 52 | [] returns [] 53 | : 54 | 55 | { 56 | 57 | } 58 | 59 | 60 | { 61 | 62 | } 63 | 64 | ( options {backtrack=false;} 65 | : ( options {backtrack=false;} 66 | : 67 | ) 68 | )* 69 | ; 70 | >> 71 | 72 | recPrimaryRule(ruleName, alts, userRetvals) ::= << 73 | returns [] 74 | options {backtrack=true;} 75 | : 76 | ; 77 | >> 78 | 79 | recRuleAlt(alt, pred) ::= "{}?=> " 80 | 81 | recRuleRef(ruleName, arg) ::= "[]" 82 | 83 | -------------------------------------------------------------------------------- /lib/ANTLR/LICENSE.txt: -------------------------------------------------------------------------------- 1 | [The "BSD license"] 2 | Copyright (c) 2011 Terence Parr 3 | C# Port (c) 2011 Sam Harwell, Tunnel Vision Laboratories, LLC 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions 8 | are met: 9 | 10 | 1. Redistributions of source code must retain the above copyright 11 | notice, this list of conditions and the following disclaimer. 12 | 2. Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | 3. The name of the author may not be used to endorse or promote products 16 | derived from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /lib/ANTLR/Targets/Antlr3.Targets.CSharp3.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beyond-code-github/LinqToQuerystring/f10c41a86eced0f2cee830f07e8fc71e35496345/lib/ANTLR/Targets/Antlr3.Targets.CSharp3.dll -------------------------------------------------------------------------------- /lib/ANTLR/Targets/Antlr3.Targets.JavaScript.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beyond-code-github/LinqToQuerystring/f10c41a86eced0f2cee830f07e8fc71e35496345/lib/ANTLR/Targets/Antlr3.Targets.JavaScript.dll -------------------------------------------------------------------------------- /lib/ANTLR/Tool/Templates/depend.stg: -------------------------------------------------------------------------------- 1 | /** templates used to generate make-compatible dependencies */ 2 | group depend; 3 | 4 | /** Generate "f : x, y, z" dependencies for input 5 | * dependencies and generated files. in and out 6 | * are File objects. For example, you can say 7 | * 8 | */ 9 | dependencies(grammarFileName,in,out) ::= << 10 | : 11 | : }; separator="\n"> 12 | >> 13 | -------------------------------------------------------------------------------- /lib/ANTLR/Tool/Templates/dot/dot.stg: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Conversion to C#: 7 | * Copyright (c) 2011 Sam Harwell, Tunnel Vision Laboratories, LLC. 8 | * All rights reserved. 9 | * 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions 12 | * are met: 13 | * 1. Redistributions of source code must retain the above copyright 14 | * notice, this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in the 17 | * documentation and/or other materials provided with the distribution. 18 | * 3. The name of the author may not be used to endorse or promote products 19 | * derived from this software without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | */ 32 | 33 | dfa(decisionRanks,states,edges,rankdir,startState,useBox) ::= << 34 | digraph NFA { 35 | rankdir=; 36 | 37 | 38 | 39 | } 40 | >> 41 | 42 | nfa(decisionRanks,states,edges,rankdir,startState) ::= << 43 | digraph NFA { 44 | rankdir=LR; 45 | 46 | 47 | 48 | } 49 | >> 50 | 51 | decision-rank(states) ::= << 52 | {rank=same; rankdir=TB; } 53 | >> 54 | 55 | edge(src,target,label,arrowhead) ::= << 56 | -> [fontsize=11, fontname="Courier", arrowsize=.7, label = "