문제

나는 단지 시작에서 프로그래밍 C#과에 대한 책을 읽을 나누어 응용 프로그램 사이트으로 세 가지 서로 다른 레이어 최고의 연습만 나는 힘든 시간을 이해하는 데 문제가있는 방법을 정확하게.Im 작업에 애완 동물 프로젝트를 lean 에 대해 더 많은 C#지는 않지만 시작하려면에 어떤 나쁜 습관이 있습니다.당신이 볼 수 있는 무슨을에 내가 가지고 보면 내가 이것을 하죠?제공하는 몇 가지 힌트를 제안이 어떻게 모든 것을 서로 다른 레이어?

프레젠테이션 층

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

비즈니스 층

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

데이터 액세스를 계층(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();
      }
    }
  }
}
도움이 되었습니까?

해결책

존,

이해해야 할 첫 번째 사항 중 하나는 계층 기반 응용 프로그램을 구축하려는 경우 ASPX 페이지 내에 직접 SQL 문을 저장해서는 안된다는 것입니다. SqlDataSource 필요). 그만큼 SqlDataSource 데이터베이스 데이터를 사용하여 응용 프로그램을 바인딩하고 업데이트하는 것이 얼마나 쉬운지를 보여주기 위해 제어되었으며 실제 응용 프로그램에서 사용하려는 의도가 아닙니다. Select를 저장하려는 경우 BL 레이어 및 DatalAyer를 갖는 목적을 무효화하기 때문입니다. /ASPX 페이지의 업데이트/삭제/삽입 문.

레이어 기반 애플리케이션 설계의 전체 목적은 교차로가 없도록 각 층을 캡슐화하는 것입니다. 각 계층은 다른 계층의 공개 인터페이스와 상호 작용하며 내부 구현에 대해서는 아무것도 모릅니다.

그러므로 실행 가능한 대안은 ObjectDataSource 제어. 이 컨트롤을 사용하면 Datalayer 또는 Biz Logic Layer에 직접 바인딩하여 데이터 층을 호출 할 수 있습니다. DatalAyer에 직접 바인딩하면 데이터베이스 테이블의 스키마를 노출시키는 데이터 구조 (예 : Datatables 또는 Dataviews)를 노출시키는 데이터 구조를 반환 할 단점이 있습니다.

따라서 권장되는 논리 흐름은 다음과 같습니다.

ASPX 페이지는 데이터 소스 컨트롤을 사용하여 BL 클래스에 바인딩합니다. 이 BL 클래스는 다음과 같은 적절한 기능을 제공합니다 GetData, UpdateData, DeleteData and InsertData (필요한 과부하 포함) 및 이러한 기능은 강력하게 입력 한 객체 또는 컬렉션을 반환합니다. ObjectDataSource 작업하고 표시 할 수 있습니다. BL 클래스의 각 공개 기능은 내부적으로 데이터베이스에 데이터베이스에 데이터를 선택/업데이트/삭제/삽입하여 데이터베이스에 데이터를 선택/업데이트/삭제/삽입합니다.

ASP.NET 에서이 레이어 기반 설계에 대한 훌륭한 소개가 QuickStarts

추신: @andy는 모든 시나리오와 함께 작동하는 일반적인 데이터 층을 언급했습니다. 보다 이 질문 그것이 어떻게 생겼는지 예를 들어.

다른 팁

가장 큰 설명의 논리에서 레이어 ASP.NET 응용 프로그램은 다음과 같은 두가지 형태로 나타납니다.첫 번째 마이크로소프트의 자신 ASP.NET 웹사이트를 서면으로 스콧 미첼 제공하는 좋은 도입하여 분리의 논리입니다.튜토리얼은 아주 말하지만 저는 그들을 발견 매우 유용합니다.URL http://www.asp.net/learn/data-access/.

두 번째 자원 내가 발견 매우 유용한 다음에는 그것에 의해 작성되었 Imar Spaanjaars 사용 .그것은 훨씬 더 많은 기술적 문서에서만 제공하는 좋은 방법이 추가의 구조를 응용 프로그램입니다.

도움이 되기를 바랍니다.

이안 수 있습니다.

코드를 궁극적으로 휴대용으로 작성하면 응용 프로그램에 3 개 (또는 그 이상) 레이어가 있습니다.

예를 들어 -이 하나의 응용 프로그램을 위해 데이터 액세스 계층을 특별히 작동시키는 대신 다시 작성할 필요가 없도록 작성하십시오. 모든 함수가 변수로 전달 될 수 있고 전역 변수에 의존하지 않도록하십시오 (또는 가능한 한 적은). 다음 프로젝트를위한 시간이되면 - DAL을 복사하여 붙여 넣고 갑자기 다시 달리고 있습니다.

그리고 그것은 끝나지 않습니다. MySQL과 MSSQL을 해석하는 DAL에 대한 하위 계층을 작성하고 싶을 수도 있습니다 (예 : 예를 들어). 또는 텍스트 위생이나 CSS 생성과 같이 수행하는 공통 기능 라이브러리가있을 수 있습니다.

언젠가 코드를 작성하면 앱을 작성하기 위해 앉아 있습니다. 대부분 이전 코드를 자르고 붙여 넣는 것이 포함됩니다. 프로그래머 Nirvana에 도달했습니다. :)

응용 프로그램 계층의 배후에있는 전체 아이디어는 각 계층이 아래 계층의 구현 세부 사항에 의존하지 않는다는 것입니다. 예를 들어, 코드에는 프레젠테이션 계층 안에 T-SQL 문이 있습니다. 즉, 데이터베이스 (하단 계층)에서 프리젠 테이션 계층의 직접적인 종속성이 있음을 의미합니다. 데이터베이스를 변경하는 경우 프레젠테이션 계층을 변경해야합니다. 이상적으로 이것은 당신이 원하는 것이 아닙니다. 프레젠테이션 계층은 데이터를 검색하는 방법에 대한 것이 아니라 데이터 제시에 대해서만 우려해야합니다. 전체 데이터베이스를 CSV 파일 (미친 아이디어)으로 옮기면 프레젠테이션 계층이이를 전혀 인식해서는 안됩니다.

따라서 이상적으로는 사용자에게 표시하려는 데이터 만 반환하는 비즈니스 계층 방법이 있습니다. 당신은 살펴 봐야합니다 ObjectDataSource 대신에 SqlDataSource. SqlDataSource 소규모 프로토 타이핑 프로젝트에는 좋지만 더 심각한 프로젝트에는 사용해서는 안됩니다.

비즈니스 계층과 데이터 계층 사이에 비슷한 분리가 있어야합니다. 데이터 계층은 일부 스토리지 위치 (데이터베이스, CSV 파일, 웹 서비스, ...)에서 원하는 데이터를 얻는 데 도움이됩니다. 다시 말하지만, 비즈니스 계층은 데이터 계층의 구현 세부 사항에 의존해서는 안됩니다. 예를 들어 SQL Server와 대화하고 있다면 반환해서는 안됩니다. SqlDataReader 비즈니스 계층에 대한 인스턴스. 이렇게하면 데이터 계층의 구현 세부 사항에 대한 비즈니스 계층의 종속성을 만듭니다. 실제 데이터베이스가 데이터를 검색하는 데이터베이스입니다.

실제로 비즈니스 계층이 데이터 계층의 구현 세부 사항에 따라 다르고 일반적으로 나쁜 것은 아닙니다. 데이터베이스를 마지막으로 전환하기로 결정한 것은 언제입니까? 그러나 종속성을 제거하고 구현 세부 사항을 분리하면 가능한 한 거의 항상 유지 관리 및 이해하기 쉬운 응용 프로그램이 발생합니다.

비슷한 설명을 찾을 수 있습니다 여기.

그의 질문의 주요 추력을 제외하고는 .NET의 내장 된 멤버십 / 프로필 / 역할 능력을 처리하도록 SQL 데이터베이스를 구성하려면 ASPNET_REGSQL을 살펴 보는 것이 좋습니다. 사용자 등을 만들거나 업데이트하기 위해 많은 Shag와 번거 로움을 제거합니다. 프로필을 많이 사용하지는 않았지만 AccessCode (예 : AccessCode)에게 추가 속성을 "TOCT"할 수 있습니다.

이미 사용자 인증 등을 수행하는 기존 DB 구조를 처리하는 경우 기존 DB 테이블과 저장 프로 시저를 활용하는 사용자 정의 멤버십 제공 업체를 만들 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top