Dapper avec Oracle en passant dans DbParameter

dapper oracle parameter-passing

Question

J'essaie Dapper avec Oracle et j'essayais d'exécuter une requête multi-résultats, mais Oracle nécessite un dbtype de refcursor.

StringBuilder query = new StringBuilder("BEGIN ");
query.Append("OPEN :rs1 FOR SELECT * FROM Table1 where key=:KEY; ");
query.Append("OPEN :rs2 FOR SELECT * FROM Table2 where key=:KEY; ");
query.Append("END;");
  • Est-il possible de passer un OracleParameter (peut-être comme DbParameter?) À Dapper? Quand j'ai essayé, ça a jeté une erreur.

  • Quel est l'avantage d'utiliser le DynamicParameter par rapport à un DbParameter (en supposant que les types sont connus, etc.)?

Réponse acceptée

  1. Une nouvelle interface a été ajoutée dans la version la plus récente qui permet de mieux contrôler le paramètre - elle a été ajoutée pour prendre en charge les TVP sur le serveur SQL, mais devrait fonctionner dans ce scénario. Cependant, je suis également assez content d'ajouter des boîtiers spéciaux pour tous les types qui ressemblent à dbparameter - et de les ajouter directement, ce qui vous permettrait d'ajouter directement un paramètre oracle.

  2. DynamicParameters concerne le nombre de paramètres à ajouter, il est donc un peu orthogonal à la discussion value vs DbParameter. Pour le moment, le code préfère généralement prendre le contrôle de l'ajout de paramètres lui-même, de sorte que l'appelant ne connaît que "un identifiant nommé Int de valeur 7" - pas de détails ado.net. Mais ça pourrait faire.


Edit: si vous voulez vraiment travailler avec des listes de paramètres (c.-à-d. List<DbParameter> etc.), vous pouvez le faire avec quelque chose comme:

public class DbParams : Dapper.SqlMapper.IDynamicParameters,
                        IEnumerable<IDbDataParameter>
{
    private readonly List<IDbDataParameter> parameters =
        new List<IDbDataParameter>();
    public IEnumerator<IDbDataParameter> GetEnumerator() {
        return parameters.GetEnumerator(); }
    IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
    public void Add(IDbDataParameter value)
    {
        parameters.Add(value);
    }
    void Dapper.SqlMapper.IDynamicParameters.AddParameters(IDbCommand command,
        Dapper.SqlMapper.Identity identity)
    {
        foreach (IDbDataParameter parameter in parameters)
            command.Parameters.Add(parameter);
    }
}

avec usage comme:

public void TestCustomParameters()
{
    var args = new DbParams {
        new SqlParameter("foo", 123),
        new SqlParameter("bar", "abc")
    };
    var result = connection.Query("select Foo=@foo, Bar=@bar", args).Single();
    int foo = result.Foo;
    string bar = result.Bar;
    foo.IsEqualTo(123);
    bar.IsEqualTo("abc");
}

qui passe le test.

Cependant, je dois insister sur le fait que je préférerais ne pas encombrer le code d'appel avec des connaissances sur les paramètres de base de données, à moins qu'il soit vraiment nécessaire de le savoir. Je préférerais de loin:

var args = new {
    foo = 123, bar = "abc"
};

qui fait exactement la même chose, mais sans passer par ADO.NET; Cela peut être particulièrement important si vous utilisez une connexion ADO.NET "décorée" (par exemple, mini-profileur) - auquel cas la couche que vous obtenez n'est pas OracleCommand / OracleConnection etc. - elle est abstraite. Cela signifie que l'ajout forcé d'un OracleParameter peut ne pas toujours fonctionner - mais ajouter un paramètre avec le nom "foo" et la valeur 123 - est assez fiable.



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