2009-02-10 9 views
0

Veuillez garder à l'esprit que je ne connais ni le C# ni le POO. Je m'excuse d'avance si cela semble une question facile pour certains. Je reviens sur mon code et cherche des moyens d'objectiver le code répétitif et de créer un cours pour que je puisse simplement réutiliser la classe. Cela étant dit, je ne cherche pas à apprendre NHibernate ou tout autre ORM pour l'instant. Je ne cherche même pas à apprendre LINQ. Je veux pirater ça pour apprendre.Création d'une classe à utiliser pour remplir des listes déroulantes, des grilles, etc., en C#

Fondamentalement, j'utilise le même bit de code pour accéder à ma base de données et remplir une liste déroulante avec les valeurs que je reçois. Un exemple:

protected void LoadSchools() 
    { 
     SqlDataReader reader; 

     var connectionString = ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString; 
     var conn = new SqlConnection(connectionString); 
     var comm = new SqlCommand("SELECT * FROM [Schools] ORDER BY [SchoolName] ASC", conn); 

     try 
     { 
      conn.Open(); 
      reader = comm.ExecuteReader(); 
      cmbEditSchool.DataSource = reader; 
      cmbEditSchool.DataBind(); 


      cmbEditSchool.Text = "Please select an existing school to edit..."; 
      if (reader != null) reader.Close(); 
     } 

     finally 
     { 
      conn.Dispose(); 
     } 
    } 

J'utilise ce même morceau de code, encore et encore tout au long de mon programme, sur des pages différentes. Le plus souvent, je remplis une liste déroulante ou une zone de liste déroulante, mais parfois je vais remplir une grille, en modifiant légèrement la requête.

Ma question est comment puis-je créer une classe qui me permettra d'appeler une procédure stockée, au lieu d'utiliser manuellement des requêtes comme mon exemple, et remplir mes différents contrôles? Est-il possible de faire avec seulement 1 méthode? J'ai seulement besoin de commencer avec les sélections. J'ai lu sur IEnumerable qui semble être l'interface appropriée à utiliser, mais comment l'utiliser?

Edité à ajouter:

Je marqué la réponse de Rorschach la réponse parce que s/il a abordé ma question IEnumerable. Je comprends également le besoin d'une couche DAL appropriée et peut-être BLL. Ce que j'essayais d'obtenir était cela. Je peux construire une liste de diffusion numérique en utilisant des ensembles de données et des adaptateurs de table qui, à la fin, me donne un ensemble de données fortement typé. Cependant, je me sens un peu éloigné du code. Je recherchais moi-même un moyen simple de construire le DAL en commençant par le code que j'ai donné plus haut. Peut-être que je ne suis pas en train de formuler ma question, ou ce que je veux, correctement. En tout cas, Rorschach était le plus proche de répondre à ma vraie question. En tout cas, Rorschach était le plus proche. Merci.

Répondre

2

Vous pouvez créer une classe qui vous permet d'appeler des procédures stockées (ceci est connu comme une classe d'accès aux données de composants (DAC), qui est généralement référencé par une classe Business Component (BC), mais cela sort du cadre de votre question).

Il y a quelques objets que vous souhaitez utiliser dans cette nouvelle classe: Microsoft.Practices.EnterpriseLibrary.Data.Database Microsoft.EnterpriseLibrary.Data.DatabaseFactory System.Data.Common.DBCommand

La classe DAC sera similaire à ce que vous avez:

public class DataAccess 
{ 
    public DataAccess() 
    { 
    } 
    public System.Collections.IEnumerable GetSchoolData() 
    { 
     string connectionString = ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString; 
     Database db = DatabaseFactory.CreateDatabase(connectionString); 
     string sqlCommand = "GetSchoolData"; 
     DbCommand comm = db.GetStoredProcCommand(sqlCommand); 
     //db.AddInParameter(comm, "SchoolId", DbType.Int32); // this is in case you want to add parameters to your stored procedure 

     return db.ExecuteDataSet(comm); 
    } 
} 

Et votre code page ressemblera à ceci:

public class SchoolPage : Page 
{ 
    public void Page_Init(object sender, EventArgs e) 
    { 
    DataAccess dac = new DataAccess(); 
    cmbEditSchool.DataSource = dac.GetSchoolData(); 
    cmbEditSchool.DataBind(); 
    } 
} 

Notez que ceci est juste pour vous aider à apprendre à fais ceci. Ce n'est pas une bonne approche du développement parce que vous ouvrez votre couche d'accès aux données au monde extérieur (ce qui est mauvais).

0

Vous devriez jeter un oeil à ADO.NET et utiliser des choses comme des ensembles de données. Linq-to-SQL serait probablement aussi utile pour vous. Mais vous ne m'en sortirez probablement pas avec un seul appel de méthode pour remplacer toutes vos opérations de données, j'en ai peur.

+0

J'apprécie l'information, cependant, je ne veux pas nécessairement utiliser un ensemble de données. Je n'ai pas besoin de données déconnectées et je veux vraiment apprendre à le faire à partir de rien ... pour ainsi dire. Je peux laisser tomber un contrôle SqlDataSource sur ma page et être fait avec lui. Cela ne m'aide pas à apprendre ... – GregD

+0

@GregD, je dirais que l'apprentissage d'une mauvaise pratique n'est pas la première étape pour «roder» l'apprentissage. L'aversion à se lier directement à un lecteur de données va beaucoup plus loin qu'une simple «préférence», c'est une mauvaise pratique pour plusieurs raisons. Relier les données directement aux formulaires est une formule perdante tout autour. –

+0

Je suppose que je ne vous suis pas Michael. Je n'ai pas d'aversion à se lier directement à un lecteur de données. J'essayais simplement de réutiliser le code et demandais un moyen de créer une classe (débuts d'un DAL) qui aurait un lecteur de données "universel" et je pourrais utiliser la classe à la place. – GregD

2

Il s'agit d'une méthode de réduction de la duplication de code. Ce n'est pas vraiment la bonne façon de configurer un Data Access Layer (DAL) et un Business Logic Layer (BLL), que je suggérerais plutôt d'apprendre.

protected void FillFromDatabase(string sql, BaseDataBoundControl dataControl) 
{ 
SqlDataReader reader = null; 

var connectionString = ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString; 
var conn = new SqlConnection(connectionString); 
var comm = new SqlCommand(sql, conn); 

try 
{ 
    conn.Open(); 
    reader = comm.ExecuteReader(); 
    dataControl.DataSource = reader; 
    dataControl.DataBind(); 
} 

finally 
{ 
    if(reader != null) 
     reader.Dispose(); 

    conn.Dispose(); 
} 
} 

alors vous pouvez l'appeler comme

const string sql = "SELECT * FROM [Schools] ORDER BY [SchoolName] ASC"; 
FillFromDatabase(sql, cmbEditSchool); 
+0

Greg m'a battu au punch presque verbatum, donc je vais juste réitérer ce qu'il dit. Ce que vous essayez de faire est une très très mauvaise idée. Vous cherchez à faire quelque chose que vous allez réutiliser partout, mais cela va juste propager une mauvaise solution non-OOP à de nombreux endroits dans votre solution. –

+0

J'ai créé ce wiki communautaire, alors n'hésitez pas à améliorer la réponse comme bon vous semble. – Greg

+0

Pourquoi est-ce une mauvaise idée? Je pensais que je me dirigeais vers la construction d'un DAL et par la suite d'une BLL et de la réutilisation du code de la même classe. – GregD

Questions connexes