Dapper les requêtes paramétrées avec les types générés automatiquement par LINQ

c# dapper linq

Question

J'utilise une combinaison de LINQ et de Dapper dans mon travail. Je remplace mon code LINQ par Dapper par endroits pour des raisons de performances. J'ai beaucoup d'objets de données LINQ créés en les faisant glisser dans le diagramme de base de données Visual Studio à partir de SQL Server.

Dans l'instance suivante, j'ai déjà un objet LINQ en mémoire et j'aimerais le transmettre à Dapper en tant que paramètres pour une requête. Par exemple:

Animal animal = con.Query<Animal>(" select * " +
        " from animal " +
        " where animalid = @AnimalId " +
        " and animaltype = @AnimalType ",
        cagedAnimal).SingleOrDefault();

cagedAnimal contient les propriétés publiques AnimalId et AnimalType avec les getters et les setters.

Cependant, lors de l'exécution de ce code, j'obtiens l'erreur suivante:

Le type: SMDApp.Models.Animal n'est pas pris en charge par dapper

Le code suivant fonctionne:

Animal animal = con.Query<Animal>(" select * " +
            " from animal " +
            " where animalid = @AnimalId " +
            " and animaltype = @AnimalType ",
            new 
            { 
            AnimalId = cagedAnimal.AnimalId, 
            AnimalType = cagedAnimal.AnimalType 
            }
            ).SingleOrDefault();

Il serait plus pratique pour moi d'utiliser un objet existant, en particulier lorsque j'utilise plusieurs propriétés de l'objet en tant que paramètre pour la requête. Quelqu'un peut-il dire pourquoi cela fonctionne pour un objet anonyme mais pas pour un objet LINQ généré automatiquement?

Edité en réponse à la réponse de Ben Robinson.

Edité une seconde fois en réponse à la réponse de Marc Gravell.

Réponse acceptée

La version courte est celle qui devrait déjà fonctionner ; basé sur l'erreur:

Le type: SMDApp.Models.CagedAnimal n'est pas pris en charge par dapper

Je conclus que soit vous transmettez en fait un new {cagedAnimal} au lieu de cagedAnimal , soit que votre CagedAnimal possède une propriété ( Parent , peut-être?) CagedAnimal est elle-même un CagedAnimal et que dapper ne peut pas comprendre. Le comportement actuel est qu'un paramètre est ajouté pour chaque propriété publique de l'objet de paramètre fourni - et s'il ne sait pas comment envoyer l'une des propriétés à la base de données, il se plaint. Vous devriez trouver qu'un simple POCO avec juste des membres de valeur fonctionne bien.

Toutefois! Notez qu'il n'essaie jamais d'analyser votre SQL - en particulier, il ne vérifie pas les paramètres dans la requête fournie. En tant que tel, l'utilisation de l'approche POCO signifie que vous ajoutez des propriétés inutiles à la requête.

Nous utilisons beaucoup Dapper, et nous utilisons simplement l'approche:

 new { obj.Foo, obj.Bar, id, key = "something else" }

Réponse populaire

Marc vient de commettre un changement pour résoudre ce problème en particulier:

  1. Nous effectuons une validation triviale avant d'envoyer des tentatives de traduction de propriétés en paramètres. Par exemple, Dapper n'enverra aucun paramètre au serveur dans ce cas: cnn.Query ("select 1", new {bla = 1}) car "bla" n'existe pas dans la chaîne. Cette validation est ignorée pour les processus stockés.

  2. L'erreur, plutôt cryptique, est maintenant corrigée et grandement améliorée.

-

Dapper n'effectuait aucune analyse de l'instruction SQL sous-jacente, par exemple:

@"select * 
from animal
where animalid = @AnimalId"

Contient un seul @AnimalId appelé @AnimalId .

Cela devient compliqué, pour être correct à 100%, vous devez gérer les cas @AnimalId : @AnimalId dans la chaîne select '@AnimalId' -- @AnimalId \* @AnimalId *\ ? La regex devient un peu délicate, je n'ai pas réfléchi à tous les cas extrêmes. Par exemple: Oracle préfixe ses paramètres avec un : ce qui complique davantage les choses.

Comme Dapper ne connaissait rien des paramètres de la chaîne, il a décidé d'envoyer chaque propriété publique en paramètre. Certaines de vos propriétés publiques ne peuvent pas être mappées sur DbParameters .




Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi