API proposal: custom interpolated string handler

Offen
#2,136 20 Kommentare 22 Reaktionen 1 zugewiesene Person Auf GitHub ansehen

@mgravell arbeitet bereits daran.

Seit 14.12.2024.

Bewertung

Dieses Issue wurde noch nicht bewertet.

Beschreibung

area:sqlbuilder feature request proposal

Right now, the preferred way of passing args to Dapper requires a second parameter, for example:

string name = ...
int id = ...
conn.Execute("""
    update customer
    set name = @name
    where id = @id
    """, new { name, id });

This works; Dapper (vanilla) has code to emit custom per-type code to extract the parameters, and DapperAOT has additional code to pre-gen that as AOT and better validation (mismatched args etc). Additional per-value parameter settings are awkward, but overall: it works.

However!

There is also a possibility to use a custom "interpolated string handler". I have a fully working prototype that allows the following:

string name = ...
int id = ...
conn.Execute($"""
    update customer
    set name = @{name}
    where id = @{id}
    """);

This is not a string, and is zero alloc, fully parameterized (SQLi safe), etc. Note that the leading @ (or : etc) is primarily because ADO.NET does not directly expose the parameter token of a given connection, but IMO it helps make it very clear what is going on.

Under the hood, this emits fundamentally the same SQL, even using the argument-expression feature to generate sensible parameter names where possible (name and id in this case). Additionally, from .NET 9 the "alt-lookup" feature of dictionaries is used to avoid allocating a new string per usage. There is zero runtime ref-emit etc needed for packing parameters - we basically trick the C# compiler into doing that work for us!

We could also potentially use the optional format parameters to convey other information, for example:l {name:1000} could set the .Size to 1000, and {qty:P=5,S=3} could set the .Precision and .Scale.

Genuine question: is this an improvement? Is this worth adding new overloads of some core methods? Is this technically nice but not worth the mental addition? Or is this hell-yeah-lets-do-this?


Separately, an analyzer in AOT is proposed to spot interpolated string uses that are susceptible to SQLi (i.e. the type is string); I would also propose that we start shipping Dapper.Advisor inside Dapper, to light up all those checks by default.

Vorherrschende Sprache
C#
Sterne
18.4k
Forks
3.7k
PR-Merge-Kennzahlen
Keine gemergten PRs in 30 T.

Entwicklungsumgebung

Dieses Projekt bietet weder Dev-Container noch Dockerfile noch Beitragsleitfaden – die Einrichtung liegt bei Ihnen. Beginnen Sie mit der README; die allgemeinen Schritte stehen in unserem Leitfaden für den ersten Beitrag.

Erste Schritte

  1. Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
  3. Forken Sie das Repository und arbeiten Sie in einem Branch.
  4. Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.

Mehr aus DapperLib/Dapper

Alle Issues in DapperLib/Dapper

Ähnliche Issues

Weitere Issues zu C#

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.