'view'에 해당되는 글 3건

Programming/.NET

1. 레이아웃 섹션

 

섹션을 사용하면 뷰(View)내부의 특정 컨텐츠영역을 공유되는 레이아웃에 렌더할 수 있습니다.

 

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

@section Top {
    <div>Top 영역</div>
}

<div>뷰 본문</div>

@section Bottom{
    <div>Bottom 영역</div>
}

 

레이아웃을 사용하는 뷰페이지(Index)의 예입니다. 섹션은 레이아웃 페이지에 표시할 내용으로서 HTML이나 Razor구문을 포함할 수 있습니다.

 

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>
</head>
<body>
    @RenderSection("Top")
    <div>
        @RenderBody()
    </div>
    @RenderSection("Bottom")
</body>
</html>

 

레이아웃 페이지에서는 RenderSection 메서드를 통해 출력할 영역을 지정합니다. 그러면 해당하는 섹션에서 뷰에 정의된 내용이 표현되고 나머지는 RenderBody 메서드로 출력됩니다.

 

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>
</head>
<body>
    @if (IsSectionDefined("Top"))
    {
        @RenderSection("Top")
    }
    else
    {
        <div>없음</div>
    }
    <div>
        @RenderBody()
    </div>
    @RenderSection("Bottom")
</body>
</html>

 

레이아웃에서 특정 세션의 정의여부는 IsSectionDefined 메서드로 확인할 수 있습니다.

 

@RenderSection("Top"false)

 

RenderSection 두번째 매개변수를 false로 전달하면 만약 해당하는 섹션이 뷰에서 정의되어 있지 않더라도 예외를 발생시키지 않도록 합니다.

 

2. 부분뷰

 

부분뷰는 여러 페이지에서 중복적으로 보여져야할 특정 컨텐츠의 내용을 담아놓은 뷰로서 다른 뷰에서 부분뷰를 포함시킴으로서 여러 뷰에서 동일한 컨텐츠를 표현하는 것이 가능합니다.

 

우선 뷰를 부분뷰로 생성하기 위해서는 뷰를 생성할때 Add View 화면에서 Create as a partial view 를 선택합니다.

 

 

부분뷰 파일이 생성되면 파일내용을 아래와 같이 작성합니다. 파일 내용은 html과 razor구문이 포함될 수 있습니다.

 

<div>
    이름 : @Html.TextBox("user_name") <br />
    아이디 : @Html.TextBox("user_id")
</div>

 

 

부분뷰를 위와 같이 만들어 두면 다른 뷰파일에서는 부분뷰의 내용이 필요한 부분에 @Html.Partial 메서드로 부분뷰를 포함시킬 수 있습니다.

 

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

@section Top {
    <div>Top 영역</div>
}

<div>뷰 본문</div>
@Html.Partial("MyPartialView")

@section Bottom{
    <div>Bottom 영역</div>
}

 

부분뷰는 일반적인 뷰와 마찬가지로 강력한 형식의 뷰로 만들면 특정 모델개체를 뷰로 전달할 수 있습니다.

 

@model object

<div>
    이름 : @(((string[])Model)[0]) <br />

    아이디 : @(((string[])Model)[1])
</div>

 

예제의 부분뷰는 IEnumerable 형식을 모델을 받는 강력한 형식의 뷰로서 전달받은 모델을 통해 배열을 열거하고 있습니다.

 

@Html.Partial("MyPartialView"new[] { "홍길동""hong" })

 

강력한 형식의 부분뷰를 포함할때는 두번째 매개변수에 전달하고자 하는 모델개체를 지정하면 됩니다.

 

3. 자식 액션

 

프로그램의 비지니스 로직에서 동적으로 생성된 데이터를 다수의 뷰에서 포함해야 하는 경우에는 해당 로직을 포함한 프로그램부분을 자식 액션으로 만들고 뷰에서 이를 포함하는 형태로 처리할 수 있습니다. 예를 들어 현재 시간과 날짜를 포함하는 특정 내용을 여러 뷰에서 포함해 출력해야 하는 경우

 

public ActionResult NowTime()
{
    return PartialView((object)DateTime.Now.ToString("yyyy년 MM월 dd일 HH시 mm분입니다."));
}

 

우선 필요한 액션메서드를 만들고 해당 메서드에서 뷰를 호출하도록 합니다. 이때 PartialView로 부분뷰를 호출하도록 하고 있으므로

 

@model string

<span> 안녕하세요 현재시간 @Model 입니다.</span>

 

뷰를 부분뷰로 만들어야 합니다. 예제에서는 강력한 형식의 부분뷰를 생성하였습니다.

 

@Html.Action("NowTime")

 

일반뷰에서는 위와 같이 Action 메서드로 자식액션을 호출할 수 있습니다. 그러면 자식액션은 부분뷰를 불러와 Action 메서드가 호출된 부분에 포함시킬것입니다.

 

@Html.Action("NowTime""MyController")

 

Action 메서드는 기본적으로 현재의 컨트롤러에서 액션메서드를 찾게 되는데 예제에서처럼 두번째 매개변수로 컨트롤러명을 지정하면 해당 컨트롤러에서 액션메서드를 찾게 됩니다.

 

그런데 NowTime 액션메서드는 /Home/NowTime 과 같은 URL요청에도 응답할 수 있습니다. 만약 이 액션메서드를 반드시 자식액션메서드의 요청에만 응답하도록 하려면

 

[ChildActionOnly]
public ActionResult NowTime()
{
    return PartialView((object)DateTime.Now.ToString("yyyy년 MM월 dd일 HH시 mm분입니다."));
}

 

위에서 처럼 ChildActionOnly 속성을 추가해 줘야 합니다.

'Programming > .NET' 카테고리의 다른 글

[C#] async / await  (0) 2018.09.04
[C#] Path  (0) 2018.08.23
[ASP.NET MVC] 뷰 (View)  (0) 2018.08.14
[C#] using static  (0) 2018.07.27
[ASP.NET MVC] 헬퍼메서드(Helper Method)  (0) 2018.07.18
[C#] extern  (0) 2018.07.03
0 0
Programming/.NET
MultiView는 내부에 여러 View 요소를 포함할 수 있으며 페이지 안에서 특정 부분을 보이거나 보이지 않도록 제어할 수 있습니다.
<asp:MultiView ID="MultiView1" runat="server">
    <asp:View ID="View1" runat="server">
        이것은 버튼<br />
        <asp:Button ID="Button1" runat="server" Text="Button" />
    </asp:View>
    <asp:View ID="View2" runat="server">
        이것은 라벨<br />
        <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
    </asp:View>
    <asp:View ID="View3" runat="server">
        이것은 텍스트박스<br />
        <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
    </asp:View>
</asp:MultiView>
<코드 1-1>

MultiView는 내부에 View요소만 추가될 수 있으며 View내부에 다시 다른 내용을 추가하는 식으로 MultiView를 구성하게 됩니다.
 
 주요속성/이벤트

(1) ActiveViewIndex

MultiView 안에 View를 배치하고 실행하면 아무것도 보이지 않는데(기본값 -1) 어떤 View를 보일지는 ActiveViewIndex 속성을 통해 지정합니다. Index순서는 0부터 시작하므로 만약 <코드 1-1>에서 이 값을 0으로 설정하면 '이것은 버튼....' 이라는 내용의 View가 보이게 될 것입니다.

따라서 당연히 ID가 View2 나 View3 인 부분이 보이게 하려면 그에 맞는 ActiveViewIndex 를 설정해야 하겠죠.

다만 MultiView 는 자체적으로 View를 이동시킬 수 있는 이벤트가 없으므로 버튼이나 기타 다른 컨트롤을 배치하여 해당 컨트롤의 이벤트 안에서 View를 이동시킬 수 있도록 처리해야 합니다.

예를 들어 <코드1-1>에서 다음과 같이 두개의 버튼을 추가하고
<asp:MultiView ID="MultiView1" runat="server" ActiveViewIndex="0">
    <asp:View ID="View1" runat="server">
        이것은 버튼<br />
        <asp:Button ID="Button1" runat="server" Text="Button" />
    </asp:View>
    <asp:View ID="View2" runat="server">
        이것은 라벨<br />
        <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
    </asp:View>
    <asp:View ID="View3" runat="server">
        이것은 텍스트박스<br />
        <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
    </asp:View>
</asp:MultiView>

<asp:Button ID="Button2" runat="server" Text="다음" OnClick="Button2_Click" />
<asp:Button ID="Button3" runat="server" Text="이전" OnClick="Button3_Click" />
추가된 버튼의 이벤트에 상황에 맞는 ActiveViewIndex 를 설정하도록 하면 됩니다.
protected void Button2_Click(object sender, EventArgs e)
{
    MultiView1.ActiveViewIndex += 1;
}

protected void Button3_Click(object sender, EventArgs e)
{
    MultiView1.ActiveViewIndex -= 1;
}

'Programming > .NET' 카테고리의 다른 글

[ASP.NET] HiddenField  (0) 2014.02.06
[ASP.NET] RequestFieldValidator  (0) 2014.02.05
[ASP.NET] MultiView 와 View  (0) 2014.02.04
[ASP.NET] Global.aspx  (0) 2014.02.03
[ASP.NET] Chart  (0) 2014.01.27
[ASP.NET] BulletedList  (0) 2014.01.23
0 0
Programming/Microsoft SQL Server

VIEW는 실제 존재하지 않는 가상적 Table로서 다른 Table에서 Data를 가져와 이를 한곳에 묶어서 보여주는 역활을 합니다. 이러한 특징을 통해 개발자는 사용자가 보길 원하는 Data만 보여줄 수 있을 뿐 아니라 VIEW가 참조하고 있는 실제 Table에 대한 접근제한(VIEW를 통해서도 Data의 추가, 삭제, 변경등이 가능합니다.)을 통해 보안성을 기대할 수 있습니다.

1. View의 생성

Create view <이름>
As
<table 조회 구문>


<이름>에는 View의 이름을 지정하며 <table 조회 구문>에서는 실제 Table을 조회하는 Select문을 작성합니다.


Create view viewDepartment
As
Select BusinessEntityID, A.DepartMentID, Name, GroupName
From HumanResources.EmployeeDepartmentHistory As A, HumanResources.Department As B
Where A.DepartmentID = B.DepartmentID;


HumanResources.EmployeeDepartmentHistory와 HumanResources.Department Table의 Join을 통해 Department의 ID와 Name, GroupName를 같이 조회하는 View를 생성합니다.


Select * From viewDepartment;


생성된 View를 조회합니다.


만일 생성된 VIEW를 변경하고자 한다면 Alter를 사용하면 됩니다.


Alter view viewDepartment
As
Select BusinessEntityID, A.DepartMentID, Name, GroupName, StartDate
From HumanResources.EmployeeDepartmentHistory As A, HumanResources.Department As B
Where A.DepartmentID = B.DepartmentID;


HumanResources.EmployeeDepartmentHistory Table에 있는 StartDate열을 View에 추가합니다.


Select * From viewDepartment;


변경된 View를 조회합니다.


View의 삭제는 Drop문을 통해 구현합니다.

Drop view viewDepartment;

앞서 보신바와 같이 View는 실제존재하는 Table를 참조하여 원하는 Data를 보여주고 있습니다. 그런데 이 상태에서 View가 참조하고 있는 Table 혹은 Table의 Column 이름(또는 형식)이 변경되는 상황이 발생하면 분명 문제가 발생할 것입니다.

이러한 문제를 방지하려면 Schemabinding Option을 사용합니다.

Create view viewDepartment With Schemabinding
As
Select BusinessEntityID, A.DepartMentID, Name, GroupName
From HumanResources.EmployeeDepartmentHistory As A, HumanResources.Department As B
Where A.DepartmentID = B.DepartmentID;

Schemabinding Option을 통해 View를 생성하면 해당View에서 쓰이는 Table(혹은 Column과 형식)이름은 변경이 불가능하게 됩니다.

Exec Sp_rename 'HumanResources.EmployeeDepartmentHistory','EmployeeDepartment'

Table이름 변경을 시도하고 있습니다.

Exec Sp_rename 'HumanResources.Department.[Name]', 'Title', 'Column'

Table의 Column이름을 변경합니다.

Alter Table HumanResources.Department Alter Column Name nVarchar(60);

Table의 Column형식을 변경합니다.

참고:
sp_rename은 명칭변환에 관한 Procedure입니다.


Schemabinding 옵션으로 Error가 발생한다는 것을 알 수 있습니다.

2. View를 통한 data변경

생성된 View만을 가지고도 Data를 Update하거나 Insert, Delete할 수 있습니다. 실제 이렇게 하기위한 특별한 방법이 있는 것은 아니므로 일반 Table과 똑같이 쓰시면 됩니다.

Update viewDepartment
Set GroupName = 'Engineering and Development'
Where BusinessEntityID = 2;

BusinessEntityID가 2인것의 GroupName을 변경하고 있습니다.

Select * From viewDepartment;

View를 확인해 보시면


뭔가 이상한듯 합니다. Update할때는 BusinessEntityID가 2인것만 변경하라고 했는데 다른 부분이 같이 변경되어 있기 때문이죠.

이런 현상이 발생한 이유는 View에서의 Data변경이 실제 Table의 Data에도 반영되기 때문입니다. 즉, GroupName열의 실제 Table에 해당하는 HumanResources.Department Table에서 변경작업이 반영되었기 때문에 이를 참조하는 View에서도 GroupName을 가져오는 부분이 전부 바뀌게 된 것입니다.

이처럼 View에서의 Data변경(Insert와 Delete 포함)은 실제 Table에도 영향을 미치게 되므로 주의해야 합니다. 또한 View에서 Data를 변경하는 작업을 할때는 View가 참조하고 있는 Table하나만을 대상으로 해야 합니다.

예를 들어 위에서 구현한 Update문에서는 HumanResources.Department Table의 GroupName열만을 변경하려고 했기 때문에 가능했지만 다음 예제와 같이 GroupName과 HumanResources.EmployeeDepartmentHistory Table에 해당하는 BusinessEntityID열의 변경을 같이 추가하는 변경작업은 불가능합니다.


Update viewDepartment
Set GroupName = 'Engineering and Development',
     BusinessEntityID = 300
Where BusinessEntityID = 2;


HumanResources.Department 와 HumanResources.EmployeeDepartmentHistory 두개의 Table을 대상으로 View를 통한 Update를 시도하였습니다.

주의:
위 예제는 이해를 돕기위한 예제일 뿐입니다. View의 제약사항이 아니라 하더라도 HumanResources.EmployeeDepartmentHistory Table의 특성상 실제로는 작동할 수 없는 Query입니다.


View를 통해 Data를 변경할 수 없는 경우는 또 있습니다. 그것은 View를 생성할때 다른 Table의 열을 그대로 가져와 생성한 것이 아닌 Sum이나 Avg혹은 기타 다른 방법을 통해서 계산된 형태의 열을 가져오는 경우오도록 구현된것 또한 변경이 불가능합니다.


뿐만 아니라 View에 대한 데이터삽입의 제한도 가능한데 예를 들어 다음과 같은 뷰가 존재한다고 가정해 보겠습니다.


Create View MyView
As
Select ProductID, OrderQty, UnitPrice, UnitPriceDiscount, LineTotal, ModifiedDate
From [Sales].[SalesOrderDetail]
Where UnitPrice >= 2039.994;


이 뷰는 SalesOrderDetail의 UnitPrice가 2039.994 이상의 데이터만 조회하도록 하는 뷰입니다. 그런데 다음과 같이 UnitPrice가 2039.994 이하의 데이터삽입이 일어나는건


Insert Into MyView
Values(100, 1, 100.000, 0.00, 2000.000, GETDATE());


논리적으로 맞지가 않습니다. 때문에 뷰에서는 뷰가 수행하는 조건과 맞지 않는 데이터 삽입요청이 오면 Check Option구문으로 차단할 수 있습니다.


Create View MyView
As
Select ProductID, OrderQty, UnitPrice, UnitPriceDiscount, LineTotal, ModifiedDate
From [Sales].[SalesOrderDetail]
Where UnitPrice >= 2039.994
With Check Option;


3. View의 Index

일반적인 View는 실제 Data를 가지지 않고 다른 Table로 부터 Data를 가져와 보여주는 역활을 합니다. 이런 View에 Index를 부여하게 되면 이 View는 다른 Table로 부터가 아닌 View에서 직접적으로 Data를 조회하게 됩니다.

그래서 Index를 가지는 View는 보통 일반 View보다 성능적으로 개선될 수 있지만 만일 이 View가 참조하고 있는 Table에서 Data변경이 발생하면 View에도 Data변경이 같이 발생하기 때문에 변경작업에는 오히려 좋지않은 영향을 끼칠 수있습니다.

따라서 이와 같은 특징을 잘 고려하여 View에 Index를 생성할지 여부를 결정해야 합니다.

View에 Index를 생성하는 방법은 다음과 같습니다.


Create Unique Clustered Index inx_viewDepartment On viewDepartment(BusinessEntityID, DepartMentID);


위에서 생성한 viewDepartment View에 BusinessEntityID와 DepartMentID열을 가지고 Index를 생성합니다.(현재 내용상 BusinessEntityID에 중복값이 있기 때문에 EusinessEntityID열만 가지고 Index를 만들 수 없는 없습니다.)

View에 Index를 생성하고 나서 해당 View를 조회 하려면 다음과 같이 할 수도 있겠으나


Select * From viewDepartment;


이것은 Index가 생성된 View에는 권장할 만한 방법이 아닙니다. Index를 제대로 타지 않기 때문이므로 되도록 다음과 같이 조회하는 것을 권장합니다.


Select *
From viewDepartment With (Noexpand);


Noexpand Option을 추가하여 View에 Index를 제대로 적용하도록 지정합니다.


4. View에 대한 상세한 정보확인

View가 생성되면 생성될때의 Create문은 sys.sql_modules에 저장됩니다.

Select * From sys.sql_modules;


sys.sql_modules는 object id별로 Data를 저장하는데 이것만 봐서는 내가 원하는 View가 어떤 id로 저장되어 있는지 알 수가 없습니다. 따라서 OBJECT_ID를 이용하여 생성한 View에 대한 object id를 얻고 이를 통해 얻어진 id값을 비교해서 조회 하여야 합니다.

Select * From sys.sql_modules
Where object_id = OBJECT_ID('viewDepartment');


이렇게 하면 View를 생성할때의 생성문을 확인할 수 있습니다.

이때 만일 View생성에 대한 Crate문을 볼 수 없도록 보안조치를 취하려면 View생성시 Encryption을 사용하여 암호화 하도록 합니다.

Create view viewDepartment With Encryption
As
Select BusinessEntityID, A.DepartMentID, Name, GroupName
From HumanResources.EmployeeDepartmentHistory As A, HumanResources.Department As B
Where A.DepartmentID = B.DepartmentID;
Select * From sys.sql_modules
Where object_id = OBJECT_ID('viewDepartment');

암호화가 처리가 정상적으로 적용되었는지 확인하기 위해 sys.sql_modules를 조회합니다.


생성문이 보여야할 definition 열이 null로 표시됨을 알 수 있습니다.

주의:
View 생성문이 한번 암호화 되면 되돌릴 수 있는 방법은 존재하지 않습니다. 따라서 암호화 하기전 다시한번 심사숙고 해야하며 View생성문 자체를 백업해 둬야 합니다.

VIEW자체에 대한 정보는 sys.view에서 확인할 수 있으며

Select * From sys.views
Where object_id = OBJECT_ID('viewDepartment');


생성한 View가 어떤 Column을 반환하는지에 대한 정보는 sys.columns에서 알 수 있습니다.

Select * From sys.columns
Where object_id = OBJECT_ID('viewDepartment');


또한 뷰가 참조하는 테이블이나 열(Column)을 확인하려면 sp_depends 프로시저를 사용합니다.

Exec sp_depends MyView;

5. 시스템 뷰


MS SQL Server는 자체적인 시스템관리를 위해 몇가지 테이블을 가지고 있습니다. 하지만 관리자를 포함한 사용자는 이 시스템테이블에 접근할 수 없으며 관련 방법자체도 제공하지 않습니다.


대신 시스템 정보 확인을 위해 시스템 테이블과 연계된 몇가지 뷰를 제공하고 있는데 이런걸 '시스템뷰'라고 합니다.


시스템뷰는 예를 들어 DB정보를 간략히 보여주는 sys.databases 와 같은 뷰가 있습니다.


Select *
From sys.databases;

'Programming > Microsoft SQL Server' 카테고리의 다른 글

동적 쿼리 실행 예시 (sp_executesql)  (0) 2013.08.22
[SQL] CTE  (0) 2011.03.07
[SQL] 뷰(VIEW)  (0) 2011.03.04
[SQL] 커서(Cursor)  (2) 2011.03.03
[SQL] 트리거(Trigger)  (2) 2011.03.02
[SQL] 사용자 정의 함수  (1) 2011.02.28
0 0
1
블로그 이미지

클리엘