Dapper.NET Valeur Inlining


Exemple

Parfois, la commodité d'un paramètre (en termes de maintenance et d'expressivité) peut être compensée par son coût en termes de performances pour le traiter en tant que paramètre. Par exemple, lorsque la taille de la page est fixée par un paramètre de configuration. Ou une valeur de statut correspond à une valeur enum . Considérer:

var orders = connection.Query<Order>(@"
select top (@count) * -- these brackets are an oddity of SQL Server
from Orders
where CustomerId = @customerId
and Status = @open", new { customerId, count = PageSize, open = OrderStatus.Open });

Le seul paramètre réel ici est customerId - les deux autres sont des pseudo-paramètres qui ne changeront pas réellement. Souvent, le SGBDR peut faire un meilleur travail s'il les détecte comme des constantes. Dapper a une syntaxe spéciale pour ceci - {=name} au lieu de @name - qui ne s'applique qu'aux types numériques. (Cela minimise toute surface d'attaque de l'injection SQL). Voici un exemple:

var orders = connection.Query<Order>(@"
select top {=count} *
from Orders
where CustomerId = @customerId
and Status = {=open}", new { customerId, count = PageSize, open = OrderStatus.Open });

Dapper remplace les valeurs par des littéraux avant d’émettre le code SQL. Le SGBDR voit donc quelque chose comme:

select top 10 *
from Orders
where CustomerId = @customerId
and Status = 3

Ceci est particulièrement utile lorsque vous autorisez les systèmes SGBDR non seulement à prendre de meilleures décisions, mais aussi à ouvrir des plans de requête que les paramètres réels empêchent. Par exemple, si un prédicat de colonne est associé à un paramètre, un index filtré avec des valeurs spécifiques sur ces colonnes ne peut pas être utilisé. Cela est dû au fait que la requête suivante peut avoir un paramètre différent de l'une de ces valeurs spécifiées.

Avec des valeurs littérales, l'optimiseur de requête peut utiliser les index filtrés car il sait que la valeur ne peut pas être modifiée dans les requêtes futures.