SQL inside C# strings, fragment editor, run query in console – Language injection updates in Rider 2018.3

The latest Rider 2018.3 EAP build extends Rider’s language injections functionality quite a bit, with SQL language support in string literals. This gives us highlighting, code completion and code analysis, and a Run in console action for SQL inside of a C# string!

For all existing and newly added language injections, we can edit fragments in a separate editor! And last but not least, we can now configure automatic language injections, so that Rider automatically recognizes language fragments inside strings.

More than enough for a long blog post! Grab a coffee or tea, sit back, and let’s dive in!

What are language injections again?

Sometimes we have to embed a piece of code in a string literal. For example, pieces of HTML inside a JavaScript string, or a quick JSON fragment inside a C# string. Rider supports marking a string literal as containing another programming language, so that we get highlighting, code completion, code analysis and more inside of a string!

Inject JSON into string literal

That’s the main premise. In case you want to read more about language injections in Rider before, go read up on them. Now let’s look at what’s new in Rider 2018.3!

SQL language injections – make working with Entity Framework and Dapper more enjoyable

For those developers using Entity Framework’s SqlQuery to work with raw SQL queries, or those using a data access framework like Dapper which is string-based, we have great news!

After setting up a database connection in Rider, we can mark any string as being a SQL fragment, and get highlighting, code completion and code analysis based on the schema of the database we are connected to!

Code completion inside a string for a connected SQL database

That’s right: code completion based on our connected SQL database, inside a C# string literal!

Note that this also works with Data Definition Language (DDL) database connections: if you have a folder containing .sql files that define tables, views, …, Rider will provide code completion for those as well.

Data definition language database code completion

Having support for injected SQL fragments should help us in writing raw SQL queries in our code, which is especially useful when using the various micro-ORM’s (such as Dapper) out there.

The Run query in console context action

For strings that contain injected SQL, Rider provides highlighting, code completion and code analysis. Not only that: database-related context actions (Alt+Enter) become available as well, such as running a query from C# string in the database console:

Run query from C# editor in database console

No more need to open up a database console and copy/paste a query in there!

Tip: check our blog series to learn more about working with databases in Rider.

Edit language injection fragments in a separate editor

Previously, when working with language injections, we would have to manually escape special characters that were not allowed inside the “host” language. For example when injecting JSON into a string, we’d still have to escape " to \".

Rider 2018.3 adds the ability to edit an injected language fragment in a separate editor, and ensures that the contents we are editing are properly escaped in the original document:

Edit language fragment in separate editor

This works for SQL as well, including context actions (Alt+Enter):

Edit SQL statement in fragment editor

Automatic language injections

Marking a string as an injected language only applies to our local Rider instance. To share language injections with team members, we can add a // language={language-name} comment on the line before the string literal. However, that does require some discipline.

Rider 2018.3 comes with automatic language injections based on patterns, so that strings similar to SELECT ... FROM ... are recognized as a SQL language injection while typing:

Automatic recognizition of SQL

We can add our own patterns in Rider’s settings, under Editor | Language Injections:

Edit automatic language injection patterns

Have a look at the existing ones for inspiration.

Additional injected languages

So far, we have covered support for SQL language injections. For Rider 2018.3, we have been hard at work to support injecting additional languages.

By merging language injection functionality from IntelliJ IDEA and ReSharper, we now support languages like CSS, HTML, JSON, regular expressions and JavaScript, as well as SQL, XML, MsBuild, YAML, and many more.

Current limitations/external annotations

When using certain types and methods, Rider knows that certain parameters accept string value containing a certain language. For example, when typing Regex.Matches(value, "{caret here}"), the editor knows the second string parameter accepts a regular expression and provides highlighting and code completion for it.

This works because we maintain a large collection of external annotations, where we keep information about the .NET base class library (BCL) and various open-source projects. The Regex.Matches example can be seen here.

Tip: check our blog series about how code annotations can help make Rider smarter on your code base!

Currently, Rider (and ReSharper) do not have external annotations that would, for example, annotate methods in Entity Framework and Dapper. The automatic language injection patterns described earlier should help for these cases.

Download Rider 2018.3 EAP and give it a try! We would love to hear your feedback on these updates!

About Maarten Balliauw

Maarten Balliauw is a Developer Advocate at JetBrains, working on .NET tools and Space. He focuses on .NET, Azure, web technologies and application performance. Maarten is a frequent speaker at various national and international events. In his free time, he brews his own beer. Follow him on Twitter or check out his personal blog.
This entry was posted in How-To's and tagged , , , , . Bookmark the permalink.

25 Responses to SQL inside C# strings, fragment editor, run query in console – Language injection updates in Rider 2018.3

  1. Ris says:

    Will this also be available as a language injection in resharper?

  2. Dwight says:

    Right on! Screw ORMs, amirite?

    • Well… no? :-) We’re using Entity Framework, with its SqlQuery() support. While the query thet is raw SQL, all other elements of the framework are still being used to create Objects from the Relational database and Map them. A similar framework would be Dapper, which is a bit more lightweight and only supports reading and not mutations. The idea of these is that you can tune your SQL query instead of relying on the framework to get it right, but still keep other benefits of the ORM.

      Good and recommended reads in case you want to check:

      * https://docs.microsoft.com/en-us/ef/ef6/querying/raw-sql
      * https://github.com/StackExchange/Dapper

      • I think you’re using the term ORM in different fashions. Strictly speaking dapper might be considered an ORM (although it doesn’t really do any relational mapping, it does unpack tuples into objects), but to others the word ORM means something larger such as EF or NHibernate.

        • Well, yeah, agree. But bottom line: those who like crafting raw SQL will definitely benefit from this one, and those who like e.g. EF’s LINQ approach benefit from regular code completion in Rider :-)

  3. PasserBy says:

    Is Rider development funded from ReSharper money? It’s kind of lame to see ReSharper being neglected.

    • We are working on a lot of architectural changes for ReSharper, and those are unfortunately a bit less visible right now. They do open a bright path to the future.

      Both projects are actively developed and there’s a lot of new features to be implemented still in both ReSharper and Rider.

      Happy to hear your feedback about both products!

  4. Davi says:

    Have you got an example of using the // language={language}? I can’t seem to get it working in 2018.3 EAP 4

  5. Paul Reid says:

    Awesome, I’ve been waiting for this IntelliJ feature for a while!

    Also for all those that feel like R# is being neglected, it’s not! The Rider team is just taking advantage of what’s already in the IntelliJ platform and making it compatible with the R# process they use to make Rider, they’re not writing brand new Rider exclusive features here. You can’t possibly expect the guys to backport the entire IntelliJ platform to R#!

  6. Dan says:

    I finally had a chance to download and install this EAP release
    I’m able to write SQL in a C# string and use the “Run query in console” feature to see the results, but the Code Completion is not working.

    Can anybody help?

  7. Pingback: JetBrainsのクロスプラットフォーム対応.NET IDE「Rider」誕生までの歴史とそのアーキテクチャ | JetBrains ブログ

  8. Steve W says:

    This is great, is there a way to make this work with F# too? I had a look at the Editor > Language Injections settings but didn’t have any luck :)

  9. Andreas Gullberg Larsen says:

    I get ‘unable to resolve variable’ when using SqlParameter to safely inject values.
    I want the schema intellisense, but I need it to shut up about these variables it is expecting to see. Any ideas?

Leave a Reply to Maarten Balliauw Cancel reply

Your email address will not be published. Required fields are marked *