2010-03-07 6 views
0

J'ai migré vers ASP.NET à partir de PHP où les requêtes sont exécutées directement. Donc, je crée toujours une connexion dans l'événement Page_Load, je le dispose après tout ce dont j'ai besoin, et j'accède aux données avec NpgsqlCommand. (Oui, j'utilise Postgresql dans mes applications ASP.NET.)Comment se connecter à une base de données dans ASP.NET?

Après avoir commencé à apprendre ASP.NET MVC, j'ai été étonné de voir à quel point il est facile d'accéder à SQL avec la chose LINQ to SQL. Mais ... Cela ne fonctionne qu'avec MS SQL. Donc, ma question est de savoir comment implémenter la même fonctionnalité dans mes applications? Comment se connecter facilement aux bases de données?

J'ai écrit mes propres classes wrapper pour se connecter à Postgresql. 1 classe par table

Ceci est une partie de la classe des étudiants:

public class Student : User 
{ 
    private static NpgsqlConnection connection = null; 

    private const string TABLE_NAME = "students"; 

    public int Id { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string Password { get; set; } 

    /// <summary> 
    /// Updates the student 
    /// </summary> 
    public void Update() 
    { 
     Connect(); 
     Run(String.Format("UPDATE " + TABLE_NAME + " SET first_name='{0}', last_name='{1}', password='{2}' WHERE id={3}", FirstName, LastName, Password, Id)); 
     connection.Dispose(); 
    } 

    /// <summary> 
    /// Inserts a new student 
    /// </summary> 
    public void Insert() 
    { 
     Connect(); 
     Run(String.Format("INSERT INTO " + TABLE_NAME + " (first_name, last_name, password) VALUES ('{0}', '{1}', '{2}')",FirstName, LastName, Password)); 
     connection.Dispose(); 
    } 

    private static void Run(string queryString) 
    { 
     NpgsqlCommand cmd = new NpgsqlCommand(queryString, connection); 
     cmd.ExecuteScalar(); 
     cmd.Dispose(); 
    } 

    private static void Connect() 
    { 
     connection = new NpgsqlConnection(String.Format("Server=localhost;Database=db;Uid=uid;Password=pass;pooling=false")); 
     connection.Open(); 
    } 

    //.... 

Comme vous voyez le problème ici est que chaque INSERT, DELETE, UPDATE demande J'utilise la méthode Connect() qui se connecte à la base de données . Je n'ai pas réalisé à quel point c'était stupide avant d'avoir à attendre 10 minutes pour avoir 500 lignes insérées, car il y avait 500 connexions à la base de données. L'utilisation de la mise en pool lors de la connexion aide, mais la connexion et le contrôle du pool lors de chaque requête sont toujours stupides. J'ai donc décidé de déplacer la propriété Connection vers une classe DB statique, et cela n'a pas fonctionné non plus, car c'est une très mauvaise idée de stocker des objets tels que des connexions dans une classe statique.

Je ne sais vraiment pas quoi faire. Oui, il y a une option pour que manullay crée les connexions dans chaque événement Page_Load et les ferme à la fin comme je le fais maintenant.

Student student = new Student { FirstName="Bob", LastName="Black" }; 
NpgsqlConnection connection = ... ; 
student.Insert(connection); 

Mais ce code est plutôt moche. Je serai vraiment reconnaissant à quelqu'un qui peut me guérir ici.

+1

Si vous voulez une connexion par demande, ce qui ne va pas avec le code de la fin de votre question? Vous créez et ouvrez une connexion lorsque vous avez d'abord besoin d'un accès db pour générer une page, puis fermez et disposez de la connexion une fois que vous avez terminé de la créer. Que cherchez-vous au-delà de cela? Vous voulez juste l'écrire une fois? Mak une classe de base ou IHttpHandler qui le fait pour vous. Autre chose? –

+0

Merci pour la réponse. Je cherche quelque chose d'aussi flexible que c'est ASP.NET MVC avec LINQ to SQL. Où vous n'avez pas besoin de penser à créer des connexions sur chaque page. Je veux juste savoir comment cela fonctionne ... Regarder les codes sources avec réflecteur ne m'a pas aidé, ces classes sont si complexes ... – Alex

Répondre

1

Je ne recommanderais pas ce design. Il est préférable d'encapsuler chaque appel de base de données, ce qui signifie que chaque appel ouvre une nouvelle connexion chaque fois que vous avez besoin de faire quelque chose sur la base de données. Cela peut sembler inefficace s'il n'y avait pas de regroupement de connexions. ASP.NET réutilisera automatiquement les connexions pour vous dans un pool. Le problème dans votre conception est qu'il n'y a rien qui garantit que la connexion sera fermée.

Ainsi, vous devriez essayer quelque chose comme

private static void Insert() 
{ 
    var sql = "Insert Into "....; 
    ExecuteActionQuery(sql); 
} 

private static void ExecuteActionQuery(string query) 
{ 
    using (var conn = new NpgsqlConnection(String.Format(connString)) 
    { 
     conn.Open(); 
     using (var cmd = new NpgsqlCommand(query, connection)) 
     { 
      cmd.ExecuteNonQuery(); 
     } 
    } 
} 

Je fais généralement quelques fonctions globales qui encapsulent les opérations standard de sorte que je dois passer seulement une requête et les paramètres et ma méthode fait le reste. Dans mon exemple, mon ExecuteActionQuery ne prend pas de paramètres mais uniquement pour la démonstration.

+0

Comme vous pouvez le voir, je dispose de l'objet connexion dans chaque insertion, suppression et sélection méthode soit en appelant la méthode Dispose() à la fin. Je vois ce que vous dites ... C'est probablement ce qui est utilisé pour LINQ to SQL ... Donc même si je crée/dispose l'objet de connexion chaque fois que je fais la requête, il ne fait rien mauvais pour toute l'application? – Alex

+1

Le regroupement de connexions a été spécialement conçu pour réduire les coûts d'ouverture et de fermeture des connexions, de sorte que vous puissiez encapsuler vos appels de base de données. A la fin, s'assurer que vous appelez disposer sur votre instance de connexion (via la construction using) après chaque appel db est plus sûr que d'essayer de se souvenir de le fermer via l'événement Unload. – Thomas

0

Pas vraiment en rapport avec votre question mais une autre solution, si vous aimez linq to sql, vous pouvez essayer DBLinq qui fournit un fournisseur Linq to SQL pour Postgresql et d'autres bases de données.

http://code.google.com/p/dblinq2007/

Questions connexes