With re-linq, it's now easier than ever to create full-featured LINQ providers.
Switch branches/tags
bugfix/RMLNQ-75-Fix-DebuggerDisplay bugfix/RMLNQ-94-Net45-Compatiblity-Fix-For-CoreCLI-v2.0 bugfix/RMLNQ-94-Net45-Compatiblity-Fix-For-CoreCLI bugfix/RMLNQ-104-NuGet-Package-Uses-Wrong-Dependencies-v2.1 bugfix/RMLNQ-104-NuGet-Package-Uses-Wrong-Dependencies bugfix/RMLNQ-105-QueryModel-Does-Not-Handle-SubQuery-Idenfiers-In-GroupJoins bugfix/RMLNQ-113-FullFrameworkTarget-Uses-NetStandard-Dependencies-When-Adding-The-Reference-v2.1 bugfix/RMLNQ-113-FullFrameworkTarget-Uses-NetStandard-Dependencies-When-Adding-The-Reference develop feature/RMLNQ-7-Preserve-Partially-Evaluated-Expressions feature/RMLNQ-28-Support-AsQueryable-ExtensionMethod feature/RMLNQ-35-Improve-Exception-In-QueryModel-GetOutputDataInfo-If-AdjustDataInfo-Fails feature/RMLNQ-41-Startup-Performance-Improvement feature/RMLNQ-55-Native-ExpressionTree-Formatting feature/RMLNQ-57-Net40-Compatibility feature/RMLNQ-59-Net35-Compatiblity feature/RMLNQ-67-Native-ExpressionTreeVisitor feature/RMLNQ-72-Support-PartialEvaluation-Of-ExtensionExpressions feature/RMLNQ-74-Sealed-Classes feature/RMLNQ-76-Remove-InheritanceHierarchy-From-GroupByWithResultSelectorExpressionNode feature/RMLNQ-83-Partial-Evaluation-Filter feature/RMLNQ-84-Replace-Custom-ExpressionTypes feature/RMLNQ-91-ExtensionPoint-For-FromClause feature/RMLNQ-93-Update-NodeTypeRegistry-For-NetNative-v2.0 feature/RMLNQ-93-Update-NodeTypeRegistry-For-NetNative feature/RMLNQ-98-Support-For-NetStandardMoniker feature/RMLNQ-99-Switch-To-VS2015 feature/RMLNQ-101-Update-BuildScript feature/RMLNQ-102-Update-AssemblyInfo-Metadata feature/RMLNQ-103-Integrate-NetCoreRtm-v2.1.0 feature/RMLNQ-103-Integrate-NetCoreRtm feature/RMLNQ-106-Add-QuerySourceMapping.Remove-API feature/RMLNQ-107-Optimize-EvaluatableTreeFindingExpressionVisitor feature/RMLNQ-109-Update-BuildScript-v2.1 feature/RMLNQ-109-Update-BuildScript feature/RMLNQ-115-Support-For-Microsoft.VisualBasic.CompilerServices.EmbededOperators master prerelease/v2.0.0-alpha.1 prerelease/v2.0.0-alpha.2 prerelease/v2.0.0-alpha.3 prerelease/v2.0.0-alpha.4 prerelease/v2.0.0-beta.1 prerelease/v2.0.0-beta.2 prerelease/v2.0.0-rc.1 prerelease/v2.1.0-rc.1 prerelease/v2.2.0-alpha.1 prerelease/v2.2.0-alpha.2 prerelease/v2.2.0-alpha.3 prerelease/v2.2.0-alpha.4 prerelease/v2.2.0-alpha.5 release/v2.0.0 release/v2.0.1 release/v2.0.2 release/v2.1.0 release/v2.1.1 release/v2.1.2 release/v2.2.0 spike/RMLNQ-7-MethodCallExpressionParser-With-Support-For-Recuding-Expressions spike/RMLNQ-7-PartialEvaluatingExpressionVisitor-Should-Not-Wrap-Lambdas support/v2.0 support/v2.1
Nothing to show
Clone or download
Type Name Latest commit message Commit time
Failed to load latest commit information.
.nuget RMLNQ-109 Set NuGet.CommandLine to v2.8.6 to prevent project.json fro… Dec 24, 2016
Build Update metadata to version '2.3.0'. Feb 6, 2018
Core.Net_3_5 Fix .NET 3.5 project file. Jun 27, 2015
Core.Net_4_0 RMLNQ-57 Change AssemblyInfo references to use shared files instead o… Feb 15, 2015
Core.Net_4_5 RMLNQ-94 Add dedicated .NET 4.5 projects to work around compatibility… Feb 8, 2016
Core Change project url to github.com/re-motion May 17, 2018
Development.Net_3_5.UnitTests RMLNQ-59 Add Tuple type for .NET 3.5 Development.UnitTests. Mar 1, 2015
Development.Net_3_5 RMLNQ-55 Separate string-building for expression trees to use ToStrin… May 17, 2015
Development.Net_4_0.UnitTests RMLNQ-57 Change AssemblyInfo references to use shared files instead o… Feb 15, 2015
Development.Net_4_0 RMLNQ-55 Separate string-building for expression trees to use ToStrin… May 17, 2015
Development.UnitTests Cleanup namespaces. Jun 21, 2015
Development RMLNQ-98 Switch Development project to use Core_Net_4_5 as dependency. Jun 16, 2016
PerformanceTests RMLNQ-41 Updated performance numbers after optimizations. Mar 22, 2015
UnitTests.Net_3_5 RMLNQ-83 Intergrate IEvaluatableExpressionFilter into EvaluatableTree… Jun 14, 2015
UnitTests.Net_4_0 RMLNQ-44 Change ReflectionUtility to internal. Mar 15, 2015
UnitTests.Net_4_5 RMLNQ-94 Add dedicated .NET 4.5 projects to work around compatibility… Feb 8, 2016
UnitTests RMLNQ-28 Add compatibility code for visiting AsQueryableResultOperato… Jan 21, 2018
license Remove Apache 2.0 License NOTICE.txt because re-linq does not contain… Mar 15, 2015
packages Fix repositories.config. Feb 23, 2016
.BuildProject RMLNQ-109 Fix release process script integration. Mar 6, 2017
.gitattributes Created gitattributes and gitignore files. Sep 2, 2014
.gitignore RMLNQ-98 Add project.json.lock to gitignore file. Jun 8, 2016
Apache-2.0.licenseheader RMLNQ-2 Dropped no longer needed license header files. Sep 5, 2014
AssemblyInfoShared.cs Update metadata to version '2.3.0'. Feb 6, 2018
Build-OneClick.cmd Fix local build script CMD file. Jun 24, 2016
Build.cmd Update documentation. Mar 3, 2016
Generate-Snk.cmd Restructured folders and added solution files etc after split. Aug 25, 2014
GitExtensions.settings RMLNQ-48 Add support for feature, hotfix, and bugfix branch merge com… Nov 15, 2014
How to Contribute.txt Restructured folders and added solution files etc after split. Aug 25, 2014
How to build.txt Update documentation. Mar 3, 2016
NuGet.config RMLNQ-98 Add .NET Core nuget feed. Jun 8, 2016
ReadMe.md Migrate documentation from Codeplex Nov 5, 2017
Relinq.dependdb.xml Added DependDB config file. Dec 3, 2014
Relinq.sln RMLNQ-101 Install ReleaseProcessScript v2.0.0-alpha.12. Jun 8, 2016
Relinq.sln.DotSettings Update ReSharper settings. Aug 5, 2017


Project Description With re-linq, it's now easier than ever to create full-featured LINQ providers.

Yes, you've heard that before. But re-linq is the real thing: it is used by Entity Framework 7 and NHibernate.

  • Instead of the IQueryable expression tree, re-linq gives you an abstract syntax tree that resembles the original LINQ query expression (the one using the from, where etc. keywords).
    • This works even when the original query was not a query expression, but a sequence of method invocations of Where(), Select() etc.
    • You can easily extend or modify quieries using this representation in your application, directly or via a Specification framework.
  • In the process, re-linq gets rid of everything that IQueryable puts between you and your desired target query language:
    • The structure is simplified (e.g., SelectMany is transformed back to multiple from-sources).
    • Transparent identifiers are removed.
    • Sub-queries are identified and can be handled as such.
    • Expressions are evaluated up-front wherever possible.
    • Special method calls inserted by Visual Basic are "normalized" so that they are handled implicitly, except if you choose to handle them differently.
  • re-linq handles even the most complex LINQ query expression, including joins, groups and nested queries.
  • re-linq gives you the tools to easily create your own provider, including:
    • A set of visitors that you just implement for your transformation.
    • A registry for translating methods to specific expressions in the target query language (like string methods, or ICollection.Contains).
    • A mechanism to specify eager fetching for related objects or collections that will automatically create the required queries.
  • re-linq is completely agnostic of the target query language. You can use it to create any dialect of SQL as well as other query languages such as XQL or Entity SQL. For instance, the NHibernate project uses re-linq to create HQL ASTs.

Depending on the differences between LINQ and the target query language you want to address, there is probably still a major piece of work ahead of you. But with re-linq this is about as simple as it can be: just what you thought was ahead of you before you discovered the internals of IQueryable, and then some more help.

There's one more potential advantage: The remaining effort is probably mostly in the semantic transformation from LINQ to the target query language, especially in cases where the target language does not support certain LINQ constructs (like sub-queries or LINQ group joins). Also, certain optimizations need to be made, e.g. in order to avoid the select n+1 problem via eager fetching. In many cases, the necessary transformations are similar between various target languages. re-linq allows you to do these transformations in its own query model representation, before you actually translate to the target language. These transformations can be shared between different LINQ providers via the re-motion contrib repository.

re-linq is part of the re-motion project. See the project home page for more interesting libraries, such as re-mix.


Related Projects

Sources The most current source code of re-linq is available on GitHub:

Binaries The re-linq releases are distributed as NuGet packages:

Versioning Starting with version 2.0, the releases follow Semantic Versioning (http://semver.org/)

License The Remotion.Linq.dll (the "Frontend") is licensed under the Apache Software License 2.0.

Contributing We have official contribution practices documented: Contributing to re-linq