Présentation, Business et de Données de la Couche
Je viens de commencer la programmation en C# et lisais à propos de la divisant votre application ou votre site web dans les trois couches différentes a été la meilleure pratique, mais je vais avoir du mal à comprendre exactement comment. Je travaille sur un projet de compagnie pour se pencher plus sur le C# mais je ne veux pas démarrer, sur tous les mauvaises habitudes. Pouvez-vous regarder ce que j'ai et voir si je suis en train de faire de ce droit? Offrir quelques conseils suggestions quant à la façon de tout casser vers le bas pour les différentes couches?
Couche De Présentation
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Project: Ruth</title>
<link href="CSS/StyleSheet.css" rel="stylesheet" type="text/css" />
</head>
<body>
<form id="form1" runat="server">
<div class="Body">
<div class="Header">
<div class="Nav">
<img src="images/Header_Main.gif" alt="" width="217" height="101" />
<div class="Menu">
<a href="Default.aspx">
<img src="images/Header_Home-Off.gif" alt="" /></a>
<a href="Default.aspx">
<img src="images/Header_About-Off.gif" alt="" /></a>
<a href="Register.aspx">
<img src="images/Header_Register-Off.gif" alt="" /></a>
<a href="Default.aspx">
<img src="images/Header_Credits-Off.gif" alt="" /></a>
</div>
</div>
</div>
<div class="Content">
<div class="CurrentlyListening">
<asp:Label ID="lblCurrentListen" runat="server" Text="(Nothing Now)" CssClass="Txt"></asp:Label>
</div>
<asp:GridView ID="gvLibrary" runat="server" AutoGenerateColumns="False" DataKeyNames="lib_id" DataSourceID="sdsLibrary" EmptyDataText="There are no data records to display." Width="760" GridLines="None">
<RowStyle CssClass="RowStyle" />
<AlternatingRowStyle CssClass="AltRowStyle" />
<HeaderStyle CssClass="HeaderStyle" />
<Columns>
<asp:BoundField DataField="artist_name" HeaderText="Artist" SortExpression="artist_name" HeaderStyle-Width="200" />
<asp:BoundField DataField="album_title" HeaderText="Album" SortExpression="album_title" HeaderStyle-Width="200" />
<asp:BoundField DataField="song_title" HeaderText="Track" SortExpression="song_title" HeaderStyle-Width="200" />
<asp:TemplateField HeaderText="DL">
<ItemTemplate>
<a href="http://####/Proj_Ruth/Data/<%# Eval("file_path") %>" class="lnk">Link</a>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="sdsLibrary" runat="server" ConnectionString="<%$ ConnectionStrings:MusicLibraryConnectionString %>" DeleteCommand="DELETE FROM [Library] WHERE [lib_id] = @lib_id" InsertCommand="INSERT INTO [Library] ([artist_name], [album_title], [song_title], [file_path]) VALUES (@artist_name, @album_title, @song_title, @file_path)" ProviderName="<%$ ConnectionStrings:MusicLibraryConnectionString.ProviderName %>" SelectCommand="SELECT [lib_id], [artist_name], [album_title], [song_title], [file_path] FROM [Library] ORDER BY [artist_name], [album_title]" UpdateCommand="UPDATE [Library] SET [artist_name] = @artist_name, [album_title] = @album_title, [song_title] = @song_title, [file_path] = @file_path WHERE [lib_id] = @lib_id">
<DeleteParameters>
<asp:Parameter Name="lib_id" Type="Int32" />
</DeleteParameters>
<InsertParameters>
<asp:Parameter Name="artist_name" Type="String" />
<asp:Parameter Name="album_title" Type="String" />
<asp:Parameter Name="song_title" Type="String" />
<asp:Parameter Name="file_path" Type="String" />
</InsertParameters>
<UpdateParameters>
<asp:Parameter Name="artist_name" Type="String" />
<asp:Parameter Name="album_title" Type="String" />
<asp:Parameter Name="song_title" Type="String" />
<asp:Parameter Name="file_path" Type="String" />
<asp:Parameter Name="lib_id" Type="Int32" />
</UpdateParameters>
</asp:SqlDataSource>
</div>
</div>
</form>
</body>
</html>
De La Couche De Gestion
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
public class User
{
DA da = new DA();
public string FirstName { get; set; }
public string LastName { get; set; }
public string EmailAddress { get; set; }
public string Password { get; set; }
public string AccessCode { get; set; }
public User(string firstName, string lastName, string emailAddress, string password, string accessCode)
{
FirstName = firstName;
LastName = lastName;
EmailAddress = emailAddress;
Password = password;
AccessCode = accessCode;
}
public void CreateUser(User newUser)
{
if (da.IsValidAccessCode(newUser.AccessCode))
{
da.CreateUser(newUser);
}
}
}
Couche d'Accès aux données (DAL)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Data.SqlTypes;
using System.Data.SqlClient;
using System.Configuration;
public class DA
{
public DA()
{
}
public bool IsValidAccessCode(string accessCode)
{
bool isValid = false;
int count = 0;
using (SqlConnection sqlCnn = new SqlConnection(ConfigurationManager.ConnectionStrings["MusicLibraryConnectionString"].ConnectionString))
{
sqlCnn.Open();
using (SqlCommand sqlCmd = new SqlCommand(String.Format("SELECT COUNT(*) FROM [AccessCodes] WHERE [accessCode_accessCode] = '{0}';", accessCode), sqlCnn))
{
count = (int)sqlCmd.ExecuteScalar();
if (count == 1)
{
isValid = true;
}
}
}
return isValid;
}
public void CreateUser(User newUser)
{
using (SqlConnection sqlCnn = new SqlConnection(ConfigurationManager.ConnectionStrings["MusicLibraryConnectionString"].ConnectionString))
{
sqlCnn.Open();
using (SqlCommand sqlCmd = new SqlCommand(String.Format("INSERT INTO [Users] (user_firstName, user_lastName, user_emailAddress, user_password, user_accessCode) VALUES ('{0}', '{1}', '{2}', '{3}', '{4}');", newUser.FirstName, newUser.LastName, newUser.EmailAddress, newUser.Password, newUser.AccessCode), sqlCnn))
{
sqlCmd.ExecuteNonQuery();
}
}
DeleteAccessCode(newUser.AccessCode);
}
public void DeleteAccessCode(string accessCode)
{
using (SqlConnection sqlCnn = new SqlConnection(ConfigurationManager.ConnectionStrings["MusicLibraryConnectionString"].ConnectionString))
{
sqlCnn.Open();
using (SqlCommand sqlCmd = new SqlCommand(String.Format("DELETE FROM [AccessCodes] WHERE [accessCode_accessCode] = '{0}';", accessCode), sqlCnn))
{
sqlCmd.ExecuteNonQuery();
}
}
}
}
OriginalL'auteur Jon H | 2009-04-29
Vous devez vous connecter pour publier un commentaire.
Jon,
L'une des premières choses à comprendre, c'est que si vous avez l'intention de construire de la couche de base des applications, alors vous ne devriez pas être stocker des instructions SQL directement dans les pages ASPX (comme le
SqlDataSource
oblige). LeSqlDataSource
de contrôle a été construite pour montrer combien il est facile de lier et de mettre à jour une application avec base de données et n'est pas destiné à être utilisé dans des applications du monde réel, car il un peu de défaites le but d'avoir un BL couche et Datalayer si vous allez stocker Select/Update/Delete/Insert dans la page ASPX.Tout l'objet de la couche de base de la conception de l'application est d'encapsuler chaque couche de sorte qu'il n'y a pas d'intersection. Chaque couche interagit avec l'interface publique de toutes les autres couches et ne sait rien au sujet de leur mise en œuvre interne.
La solution de rechange viable, donc, est d'utiliser le
ObjectDataSource
de contrôle. Cette commande vous permet de lier directement à un DataLayer ou à un Biz de la couche logique qui à son tour peut appeler le Datalayer. La liaison à un Datalayer directement a l'inconvénient que vous serez de retour à des structures de données qui exposent le schéma des tables de base de données (par exemple, les tables de données ou de DataViews).Ainsi, le débit recommandé de logique est comme suit:
La page ASPX utilise un contrôle de source de données pour le lier à un BL de la classe.
Ce BL classe fournit des fonctions telles que
GetData, UpdateData, DeleteData and InsertData
(avec les surcharges) et ces fonctions retournent des objets fortement typés ou les collections de laObjectDataSource
peut travailler avec et de les afficher.Chaque fonction publique dans le BL de la classe appelle en interne dans le DataLayer pour sélectionner/mettre à jour/supprimer/insérer des données vers/à partir de la base de données.
Une excellente introduction à cette couche de base de conception dans ASP.NET est fourni dans le Démarrages rapides
P. S: @Andy mentionné générique datalayers qui fonctionnent avec tous les scénarios. Voir cette question pour un exemple de ce à quoi il pourrait ressembler.
Comment qualifieriez-vous mon code ci-dessus?
Vous n'avez pas pour fermer explicitement parce que vous êtes à l'aide d'un "utilisation de construire", qui permettra de disposer de la connexion. Cela dit, vous devriez probablement toujours à proximité pour plus de clarté.
Aussi, il serait présomptueux de ma part de taux de votre code ci-dessus. N'hésitez pas à essayer lorsque vous êtes en train d'apprendre. Vous êtes sur la bonne voie. Et hey, merci pour l'acceptation de ma réponse! 😉
OriginalL'auteur Cerebrus
La plus grande explication de la logique des calques dans ASP.NET les demandes proviennent de deux sources. La première est de Microsoft ASP.NET site écrit par Scott Mitchell, il offre une bonne introduction à la séparation de la logique. Les tutoriels sont très verbeux, mais je les ai trouvé très utile. L'URL est http://www.asp.net/learn/data-access/.
La deuxième ressource que j'ai trouvé très utile a suivi et il a été écrit par Imar Spaanjaars et est disponible ici. Il est beaucoup plus technique article mais offre un excellent moyen d'ajouter de la structure à votre demande.
J'espère que ça aide.
Ian.
Je suis content que vous l'aimez, j'ai trouvé une grande ressource intermédiaire à apprendre.
Je viens de regardé Imar de l'article. Juste une question simple - n'est-il pas l'introduction de la tristement célèbre "Anémique Modèle de Domaine" ? Je veux dire, pourquoi devrais-je me séparer de mon entreprise logique de mon business objects, de toute façon? Et si je le fais, pourquoi aurais-je encore appeler l'objet de l'entreprise "business objects" ??
OriginalL'auteur Ian Roke
Si vous écrivez votre code afin d'être en fin de compte portable, vous trouverez que vous avez 3 (ou plus!) les couches de votre application.
Par exemple - au lieu de faire de votre Couche d'Accès aux Données de travail spécifiquement pour cette application, de l'écrire, de sorte que vous n'aurez jamais à écrire de nouveau. Assurez-vous que toutes vos fonctions peuvent être transmis variables et que vous ne comptez pas sur les variables globales (ou aussi peu que possible). Quand vient le temps pour votre prochain projet - copier et coller votre DAL et soudain, vous êtes à nouveau opérationnel.
Et il ne s'arrête pas là - bas, vous pourriez écrire une sous-couche pour votre DAL qui interprète entre MySQL et MSSQL (juste un exemple). Ou vous pourriez avoir une bibliothèque de fonctions communes que vous effectuez, comme le texte de l'assainissement ou CSS génération ou quelque chose.
Si vous écrivez votre code de façon à ce qu'un jour, vous vous asseyez pour écrire une application - et la plupart du temps il s'agit de couper et de coller de code précédent, vous avez atteint le programmeur de nirvana. 🙂
même si elles ont des objets et des classes, il peut encore être différents fichiers de projet pour chaque
Les deux paradigmes sont appropriés pour les différents scénarios. Parfois, il est préférable d'avoir une datalayer pour chaque projet. Alors que j'utilise générique datalayers pour la plupart de mes besoins, je comprends la nécessité de construire spécifique datalayers et ne croient pas qu'ils doivent être découragées.
Merci! Qui a été utile et je pense comprendre de quoi vous parlez, à peu près universel DAL qui imite quel que soit votre DB est.
OriginalL'auteur Andy Moore
L'idée derrière la superposition d'une application, c'est que chaque couche ne dépend pas de détails d'implémentation de la couche(s) ci-dessous. Par exemple, dans votre code, vous avez une instruction T-SQL à l'intérieur de la couche de présentation. Cela signifie que vous avez une dépendance directe de la couche de présentation sur votre base de données (couche de fond). Si vous effectuez un changement dans votre base de données, vous devez également faire un changement dans votre couche de présentation. Dans l'idéal, ce n'est pas ce que vous voulez. La couche de présentation devrait seulement être préoccupé par la présentation des données, pas sur la façon de le récupérer. Supposons que vous vous déplacez l'ensemble de votre base de données dans des fichiers CSV (je sais, idée folle), puis la couche de présentation ne doit pas être conscients de ce tous les.
Donc, idéalement, vous avez une couche de méthode qui retourne uniquement les données que vous souhaitez afficher à l'utilisateur. Vous devriez jeter un oeil à
ObjectDataSource
au lieu deSqlDataSource
.SqlDataSource
est agréable pour les petits projets de prototypage, mais vous ne devriez pas l'utiliser pour tout plus de projets sérieux.Entre la couche métier et la couche de données, vous devriez avoir une semblable séparation. La couche de données est responsable de l'obtention de données que vous voulez de certaines emplacement de stockage (base de données, fichier CSV, web services, ...). Encore une fois, dans l'idéal, la couche ne doit pas dépendre des détails de mise en œuvre de la couche de données. Si vous parlez à SQL Server par exemple, vous ne devriez pas retourner un
SqlDataReader
instance de votre couche de gestion. En faisant cela, vous créez une dépendance de votre couche de gestion sur un détail de l'implémentation de votre couche de données: la base de données réelle, il est en train de récupérer des données à partir d'.Dans la pratique, vous verrez que la couche de gestion ne dépend pas de détails de mise en œuvre de la couche de données, d'une certaine façon ou d'une autre, et généralement ce n'est pas une mauvaise chose. Quand était la dernière fois que vous avez décidé de changer de base de données? Mais l'élimination des dépendances et l'isolement des détails de mise en œuvre, autant que possible, presque toujours des résultats dans une application qui est plus facile à maintenir et à comprendre.
Vous pouvez trouver une explication similaire ici.
OriginalL'auteur Ronald Wildenberg
comme une part à l'objectif principal de sa question, je vous recommande de regarder ASPNET_REGSQL pour configurer votre base de données SQL pour gérer .Net intégré de membres /profil /rôle capacités. Il serait de supprimer beaucoup de shag et les tracas de la création et de la mise à jour des utilisateurs, etc. Je n'ai pas utilisé le profil énormément, mais il vous permet de "virer de bord sur les" attributs supplémentaires à votre utilisateur, par exemple AccessCode.
Si vous avez affaire à une base de données existante structure qui déjà ne l'authentification de l'utilisateur, etc., vous pouvez créer un personnalisé du fournisseur d'appartenances qui permettrait de tirer parti de la base de données existante de tables et procédures stockées.
OriginalL'auteur Mike Kingscott