Recherche…


Introduction

ADO (ActiveX Data Objects) .Net est un outil fourni par Microsoft qui permet d'accéder à des sources de données telles que SQL Server, Oracle et XML via ses composants. Les applications frontales .Net peuvent récupérer, créer et manipuler des données, une fois qu'elles sont connectées à une source de données via ADO.Net avec les privilèges appropriés.

ADO.Net fournit une architecture sans connexion. C'est une approche sécurisée pour interagir avec une base de données, car la connexion ne doit pas être maintenue pendant toute la session.

Remarques

Une remarque sur le paramétrage des SQL avec Parameters.AddWithValue : AddWithValue n'est jamais un bon point de départ. Cette méthode repose sur l'inférence du type de données à partir de ce qui est transmis. Avec cela, vous pouvez vous retrouver dans une situation où la conversion empêche votre requête d' utiliser un index . Notez que certains types de données SQL Server, tels que char / varchar (sans précéder "n") ou date n'ont pas de type de données .NET correspondant. Dans ces cas, vous devez utiliser Add avec le type de données approprié .

Exécuter des instructions SQL en tant que commande

// Uses Windows authentication. Replace the Trusted_Connection parameter with
// User Id=...;Password=...; to use SQL Server authentication instead. You may
// want to find the appropriate connection string for your server.
string connectionString = @"Server=myServer\myInstance;Database=myDataBase;Trusted_Connection=True;"

string sql = "INSERT INTO myTable (myDateTimeField, myIntField) " +
    "VALUES (@someDateTime, @someInt);";

// Most ADO.NET objects are disposable and, thus, require the using keyword.
using (var connection = new SqlConnection(connectionString))
using (var command = new SqlCommand(sql, connection))
{
    // Use parameters instead of string concatenation to add user-supplied
    // values to avoid SQL injection and formatting issues. Explicitly supply datatype.

    // System.Data.SqlDbType is an enumeration. See Note1
    command.Parameters.Add("@someDateTime", SqlDbType.DateTime).Value = myDateTimeVariable;
    command.Parameters.Add("@someInt", SqlDbType.Int).Value = myInt32Variable;

    // Execute the SQL statement. Use ExecuteScalar and ExecuteReader instead
    // for query that return results (or see the more specific examples, once
    // those have been added).

    connection.Open();
    command.ExecuteNonQuery();
}

Remarque 1: Veuillez consulter l' énumération SqlDbType pour la variante spécifique à MSFT SQL Server.

Note 2: Veuillez voir MySqlDbType Enumeration pour la variante spécifique à MySQL.

Meilleures pratiques - Exécution d'instructions SQL

public void SaveNewEmployee(Employee newEmployee)
{
    // best practice - wrap all database connections in a using block so they are always closed & disposed even in the event of an Exception
    // best practice - retrieve the connection string by name from the app.config or web.config (depending on the application type) (note, this requires an assembly reference to System.configuration)
    using(SqlConnection con = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["MyConnectionName"].ConnectionString))
    {
        // best practice - use column names in your INSERT statement so you are not dependent on the sql schema column order
        // best practice - always use parameters to avoid sql injection attacks and errors if malformed text is used like including a single quote which is the sql equivalent of escaping or starting a string (varchar/nvarchar)
        // best practice - give your parameters meaningful names just like you do variables in your code
        using(SqlCommand sc = new SqlCommand("INSERT INTO employee (FirstName, LastName, DateOfBirth /*etc*/) VALUES (@firstName, @lastName, @dateOfBirth /*etc*/)", con))
        {
            // best practice - always specify the database data type of the column you are using
            // best practice - check for valid values in your code and/or use a database constraint, if inserting NULL then use System.DbNull.Value
            sc.Parameters.Add(new SqlParameter("@firstName", SqlDbType.VarChar, 200){Value = newEmployee.FirstName ?? (object) System.DBNull.Value});
            sc.Parameters.Add(new SqlParameter("@lastName", SqlDbType.VarChar, 200){Value = newEmployee.LastName ?? (object) System.DBNull.Value});

            // best practice - always use the correct types when specifying your parameters, Value is assigned to a DateTime instance and not a string representation of a Date
            sc.Parameters.Add(new SqlParameter("@dateOfBirth", SqlDbType.Date){ Value = newEmployee.DateOfBirth });

            // best practice - open your connection as late as possible unless you need to verify that the database connection is valid and wont fail and the proceeding code execution takes a long time (not the case here)
            con.Open();
            sc.ExecuteNonQuery();
        }

        // the end of the using block will close and dispose the SqlConnection
        // best practice - end the using block as soon as possible to release the database connection
    }
}

// supporting class used as parameter for example
public class Employee
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime DateOfBirth { get; set; }
}

Meilleure pratique pour travailler avec ADO.NET

  • La règle de base est d'ouvrir la connexion pour un minimum de temps. Fermez la connexion explicitement une fois l'exécution de votre procédure terminée, cela renverra l'objet de connexion au pool de connexions. Taille maximale du pool de connexion par défaut = 100. Le regroupement de connexions améliore les performances de la connexion physique à SQL Server. Regroupement de connexions dans SQL Server
  • Enveloppez toutes les connexions de base de données dans un bloc using afin qu'elles soient toujours fermées et éliminées même en cas d'exception. Voir l' utilisation de Statement (C # Reference) pour plus d'informations sur l'utilisation des instructions
  • Récupère les chaînes de connexion par nom depuis app.config ou web.config (selon le type d'application)
  • Toujours utiliser les paramètres pour les valeurs entrantes pour
    • Eviter les attaques par injection SQL
    • Évitez les erreurs si du texte mal formé est utilisé, y compris un guillemet simple qui équivaut à SQL pour échapper ou démarrer une chaîne (varchar / nvarchar)
    • Permettre au fournisseur de base de données de réutiliser les plans de requête (non pris en charge par tous les fournisseurs de bases de données), ce qui augmente l'efficacité
  • Lorsque vous travaillez avec des paramètres
    • Le type de paramètres SQL et la non-concordance de taille sont une cause fréquente d'échec d'insertion / mise à jour / sélection
    • Donnez des noms significatifs à vos paramètres SQL, tout comme vous faites des variables dans votre code
    • Indiquez le type de données de base de données de la colonne que vous utilisez, cela garantit que les types de paramètres incorrects ne sont pas utilisés, ce qui pourrait entraîner des résultats inattendus
    • Validez vos paramètres entrants avant de les transmettre à la commande (comme dit le proverbe, " garbage in, garbage out "). Valider les valeurs entrantes le plus tôt possible dans la pile
    • Utilisez les types corrects lors de l'attribution de vos valeurs de paramètre, par exemple: n'affectez pas la valeur de chaîne d'un DateTime, mais assignez une instance DateTime réelle à la valeur du paramètre
    • Spécifiez la taille des paramètres de type chaîne. Cela est dû au fait que SQL Server peut réutiliser les plans d'exécution si le type et la taille des paramètres correspondent. Utilisez -1 pour MAX
    • N'utilisez pas la méthode AddWithValue , la raison principale est qu'il est très facile d'oublier de spécifier le type de paramètre ou la précision / l'échelle si nécessaire. Pour plus d'informations, voir Peut-on arrêter d'utiliser AddWithValue déjà?
  • Lors de l'utilisation de connexions de base de données
    • Ouvrez la connexion le plus tard possible et fermez-la dès que possible. Ceci est une directive générale lorsque vous travaillez avec une ressource externe
    • Ne partagez jamais les instances de connexion à la base de données (exemple: le fait qu'un singleton héberge une instance partagée de type SqlConnection ). Demandez à votre code de toujours créer une nouvelle instance de connexion à la base de données en cas de besoin, puis de supprimer le code d'appel et de le «jeter» lorsqu'il est terminé. La raison en est
      • La plupart des fournisseurs de bases de données disposent d'une sorte de pool de connexions, ce qui fait que la création de nouvelles connexions gérées est peu coûteuse.
      • Il élimine les erreurs futures si le code commence à fonctionner avec plusieurs threads

Utilisation d'interfaces communes pour extraire des classes spécifiques à un fournisseur distant

var providerName = "System.Data.SqlClient";    //Oracle.ManagedDataAccess.Client, IBM.Data.DB2
var connectionString = "{your-connection-string}";
//you will probably get the above two values in the ConnectionStringSettings object from .config file

var factory = DbProviderFactories.GetFactory(providerName);
using(var connection = factory.CreateConnection()) {    //IDbConnection
    connection.ConnectionString = connectionString;
    connection.Open();
    
    using(var command = connection.CreateCommand()) {    //IDbCommand
        command.CommandText = "{query}";
        
        using(var reader = command.ExecuteReader()) {    //IDataReader
            while(reader.Read()) {
                ...
            }
        }
    }
}


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow