表示,业务层和数据层 [英] Presentation, Business and Data Layer

查看:313
本文介绍了表示,业务层和数据层的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚开始在C#编程,并阅读将您的应用程序/网站成三个不同的层次是最好的做法,但我有一个很难究竟如何理解。 Im在一个宠物项目合作,更多了解C#,但我不想要开始什么坏习惯。你可以看看我有什么,看看我这样做对吗?提供了一些提示,建议如何突破都记录下来,以不同的层?



表现层



 < %@页面语言=C#AutoEventWireup =真的CodeFile =Default.aspx.cs继承=_默认%GT; 

< DOCTYPE HTML PUBLIC - // W3C // DTD XHTML 1.0过渡// ENhttp://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional! DTD>
< HTML的xmlns =http://www.w3.org/1999/xhtml>
<头=服务器>
<标题>项目:露丝< /标题>
<链接HREF =CSS / stylesheet.css中相对=样式类型=文/ CSS/>
< /头>
<身体GT;
<表ID =form1的=服务器>
< DIV CLASS =身体>
< DIV CLASS =页眉>
< DIV CLASS =导航>
< IMG SRC =图像/ Header_Main.gifALT =WIDTH =217HEIGHT =101/>
< DIV CLASS =菜单>
将; A HREF =Default.aspx的>
< IMG SRC =图像/ Header_Home-Off.gifALT =/>< / A>
将; A HREF =Default.aspx的>
< IMG SRC =图像/ Header_About-Off.gifALT =/>< / A>
将; A HREF =Register.aspx>
< IMG SRC =图像/ Header_Register-Off.gifALT =/>< / A>
将; A HREF =Default.aspx的>
< IMG SRC =图像/ Header_Credits-Off.gifALT =/>< / A>
< / DIV>
< / DIV>
< / DIV>
< DIV CLASS =内容>
< DIV CLASS =CurrentlyListening>
< ASP:标签ID =lblCurrentListen=服务器文本=(没有现在)的CssClass =TXT>< / ASP:标签>
< / DIV>
< ASP:GridView控件ID =gvLibrary=服务器的AutoGenerateColumns =FALSE的DataKeyNames =lib_id的DataSourceID =sdsLibraryEmptyDataText =没有数据记录,显示 WIDTH =760网格=无>
< RowStyle的CssClass =RowStyle/>
< AlternatingRowStyle的CssClass =AltRowStyle/>
< HeaderStyle的CssClass =HeaderStyle/>
<柱体和GT;
< ASP:BoundField的数据字段=这位演出的HeaderText =艺术家的SortExpression =这位演出HeaderStyle-WIDTH =200/>
< ASP:BoundField的数据字段=ALBUM_TITLE的HeaderText =专辑的SortExpression =ALBUM_TITLEHeaderStyle-WIDTH =200/>
< ASP:BoundField的数据字段=SONG_TITLE的HeaderText =追踪的SortExpression =SONG_TITLEHeaderStyle-WIDTH =200/>
< ASP:的TemplateField的HeaderText =DL>
<&ItemTemplate中GT;
将; A HREF =HTTP:// #### / Proj_Ruth /数据/&下;%#评估和演示(FILE_PATH)%>中类=LNK>链接< / A>
< / ItemTemplate中>
< / ASP:的TemplateField>
< /专栏>
< / ASP:GridView的>
< ASP:SqlDataSource的ID =sdsLibrary=服务器的ConnectionString =<%$的ConnectionStrings:MusicLibraryConnectionString%>中DeleteCommand会=删除[库],其中[lib_id] = @lib_id的InsertCommand =INSERT INTO [图库]([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 [图库] ORDER BY [ARTIST_NAME],[ALBUM_TITLE]的UpdateCommand =UPDATE [图库] SET [ARTIST_NAME] = @ ARTIST_NAME,[ALBUM_TITLE] = @album_title,[SONG_TITLE] = @song_title,[FILE_PATH] = @file_path WHERE [lib_id] = @lib_id>
< DeleteParameters>
< ASP:参数名称=lib_idTYPE =的Int32/>
< / DeleteParameters>
< InsertParameters>
< ASP:参数名称=这位演出类型=字符串/>
< ASP:参数名称=ALBUM_TITLE类型=字符串/>
< ASP:参数名称=SONG_TITLE类型=字符串/>
< ASP:参数名称=FILE_PATH类型=字符串/>
< / InsertParameters>
< UpdateParameters>
< ASP:参数名称=这位演出类型=字符串/>
< ASP:参数名称=ALBUM_TITLE类型=字符串/>
< ASP:参数名称=SONG_TITLE类型=字符串/>
< ASP:参数名称=FILE_PATH类型=字符串/>
< ASP:参数名称=lib_idTYPE =的Int32/>
< / UpdateParameters>
< / ASP:SqlDataSource的>
< / DIV>
< / DIV>
< /表及GT;
< /身体GT;
< / HTML>



业务层



 使用系统; 
使用System.Collections.Generic;
使用System.Linq的;
使用的System.Web;

公共类用户
{
哒哒=新DA();

公共字符串名字{获得;组; }
公共字符串名字{获得;组; }
公共字符串EmailAddress的{搞定;组; }
公共字符串密码{搞定;组; }
公共字符串AccessCode {搞定;组; }

公众用户(串名字,字符串姓氏,EMAILADDRESS字符串,字符串密码,串accessCode)
{
姓=名字;
姓氏= lastName的;
EmailAddress的= EMAILADDRESS;
密码=密码;
AccessCode = accessCode;
}

公共无效CREATEUSER(用户NEWUSER)
{
如果(da.IsValidAccessCode(newUser.AccessCode))
{
达.CreateUser(NEWUSER);
}
}
}

数据访问层(DAL)

 使用系统; 
使用System.Collections.Generic;
使用System.Linq的;
使用的System.Web;
使用System.Data这;使用System.Data.SqlTypes中
;
使用System.Data.SqlClient的;
使用System.Configuration;

公共类DA
{
公共DA()
{
}

公共BOOL IsValidAccessCode(字符串accessCode)
{
BOOL的isValid = FALSE;
诠释计数= 0;使用


{
sqlCnn.Open()(SqlConnection的sqlCnn =新的SqlConnection(ConfigurationManager.ConnectionStrings [MusicLibraryConnectionString]的ConnectionString));使用
(的SqlCommand SQLCMD =新的SqlCommand(的String.Format(SELECT COUNT(*)FROM [AccessCodes],其中[accessCode_accessCode] ='{0};,accessCode),sqlCnn))
{
计数=(INT)sqlCmd.ExecuteScalar();
如果(计数== 1)
{
的isValid = TRUE;
}
}
}
返回的isValid;
}

公共无效CREATEUSER(用户NEWUSER)
{使用(SqlConnection的sqlCnn =新的SqlConnection(ConfigurationManager.ConnectionStrings [MusicLibraryConnectionString]。的ConnectionString))$
b $ b {
sqlCnn.Open();使用(的SqlCommand SQLCMD =新的SqlCommand(的String.Format(INSERT INTO [用户](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);
}

公共无效DeleteAccessCode(字符串accessCode)
{使用(SqlConnection的sqlCnn =新的SqlConnection(ConfigurationManager.ConnectionStrings [MusicLibraryConnectionString]。的ConnectionString))$
b $ b {
sqlCnn.Open();使用
(的SqlCommand SQLCMD =新的SqlCommand(的String.Format(删除[AccessCodes],其中[accessCode_accessCode] ='{0};,accessCode),sqlCnn))
{
sqlCmd.ExecuteNonQuery();
}
}
}
}


解决方案

乔恩,



其中的第一件事情要明白的是,如果你打算建立基于图层的应用程序,那么你不应该存储SQL语句直接在ASPX页面(如的SqlDataSource 要求)。在的SqlDataSource 控制的建立是为了证明它是多么容易结合并更新数据库数据的应用程序,并且不打算在现实世界中的应用中使用,因为它有点违背了有一个BL层和数据层的目的,如果你要存储选择/更新/删除在ASPX页面/ Insert语句。



基于图层的应用程序的全部目的设计是封装的每个层,使得没有交集。每一层与其它层的公共接口进行交互,什么都不知道关于他们的内部实现。



的可行的替代,因此要使用 ObjectDataSource控件控制。这种控制可以让你直接绑定到数据层或到商务逻辑层这反过来又可以调用数据层。绑定到数据层直接拥有,你将返回其暴露数据库表的模式(适用于如数据表或DataViews的)数据结构的缺点。



因此,逻辑的推荐流程如下:



ASPX页面使用DataSource控件绑定到BL类。
本BL类提供了相应的功能,如的GetData,的UpdateData,DeleteData和InsertData (带任何所需的过载),这些函数返回强类型的对象或集合的 ObjectDataSource控件可以和显示器。
在BL类的每个公共函数在内部调用到数据层来选择/更新/从数据库中删除/插入数据/



这是很好的介绍在快速入门



PS :@Andy提到,所有方案工作的通用datalayers。请参见这个问题对什么例子会是什么样子。


I just started programming in C# and was reading about dividing your application / website into the three different layers was the best practice but I am having a hard time understanding exactly how. Im working on a pet project to lean more about C# but I dont want to start on any bad habits. Can you look at what I have and see if I am doing this right? Offer some hints suggestions as to how to break everything down to the different layers?

Presentation Layer

<%@ 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>

Business Layer

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);
    }
  }
}

Data Access Layer (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();
      }
    }
  }
}

解决方案

Jon,

One of the first things to understand is that if you intend to build layer-based applications, then you should not be storing SQL statements directly within ASPX pages (as the SqlDataSource requires). The SqlDataSource control was built to demonstrate how easy it is to bind and update an application with database data and is not intended to be used in real world applications, because it kinda defeats the purpose of having a BL layer and Datalayer if you are going to store Select/Update/Delete/Insert statements in the ASPX page.

The whole purpose of layer-based application design is to encapsulate each layer so that there is no intersection. Each layer interacts with the public interface of the other layers and knows nothing about their internal implementation.

The viable alternative, therefore, is to use the ObjectDataSource control. This control allows you to bind directly to a DataLayer or to a Biz logic layer which in turn can call the Datalayer. Binding to a Datalayer directly has the drawback that you will be returning data structures which expose the schema of the database tables (for e.g., DataTables or DataViews).

So, the recommended flow of logic is as follows:

The ASPX page uses a DataSource control to bind to a BL class. This BL class provides appropriate functions such as GetData, UpdateData, DeleteData and InsertData (with any required overloads) and these functions return strongly typed objects or collections that the ObjectDataSource can work with and display. Each public function in the BL class internally calls into the DataLayer to select/update/delete/insert data to/from the database.

An excellent introduction to this layer based design in ASP.NET is provided in the Quickstarts

P.S: @Andy mentioned generic datalayers that work with all scenarios. See this question for an example of what it would look like.

这篇关于表示,业务层和数据层的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆