블로그 이미지
* Microsoft MVP - Windows Development 2014 ~ 2020 http://youtube.com/FutureOfDotNet kaki104

카테고리

List All (601)
Visual Studio (6)
Blazor (2)
Windows App(Universa.. (100)
Xamarin Forms (4)
Bot Framework (19)
Azure (9)
Windows 10 (52)
WPF (7)
Facebook News & Tips (158)
Windows 8&8.1 (113)
Windows Phone 8 (42)
Silverlight (37)
HTML5 & MVC4 (16)
Portable Class Library (2)
Uncategorised Tips a.. (3)
Kinect for Windows (2)
ETC (12)
kaki104 Scrap (4)
App News (11)
Total543,762
Today10
Yesterday62

처음에 Streamlined Operation의 맛을 보았을 때 황당했었는데.. 마치 유주얼서스팩트의 마지막을 보는 듯한..느낌이였죠, 그런데, 그걸 글로 표현해서 보여줄려면 어떻게 해야 할까..고민하다가 제목의 주제로 추가 작성을 하기로 했다.


1. 서버사이드 기술과 클라이언트 사이드 기술
정리를 하고 시작해 보자.

1-1. SL5_BOARD.Web 프로젝트에서 사용되는 기술
: SQL Server Compact 4.0 + Entity Framework 4.1 (Streamlined Database)
: 서버단에서는 SL5_BOARD_DBCONTEXT를 통해 모든 데이터를 관리, 그렇기 때문에 LINQ쿼리를 통해서 마음대로 불러내고 저장하고 떡주무르듯 할 수 있음

1-2. SL5_BOARD 프로젝트에서 사용되는 기술
: WCF RIA Service Support EF4.1
: 서버에 있는 데이터를 일단은 클라이언트까지 전송하는 기능, 전송된 데이터를 관리하는 기능, 하지만, 역시 데이터가 서버에 존재 하기 때문에 클라이언트까지 가지고 오는 것이 선행되어야 함


2. 짐승같은 코딩과 인간같은 코딩

위의 둘은 요렇게 서로 연결이 되어있다..(이렇게 연결시키기 위해서 열심히 이것 저것 했으니..되어야징..) 그런데 연결을 왜 해 놓은걸까? 방금 전 소스상에서 연결해 놓은 덕을 보았나? 그렇게 할려면 뭐한다고 연결하는 것인가? 음음음...그러게..여태까지 짐승같은 코딩을 해 놓은 거내~~~~~~~~~~~~~이제 짐승코딩에서 인간코딩으로 바꿔보자..그래서 인간이 되어야 인간답게 살 수 있는 거다.


2-2. 짐승같은 코딩
BOARD_MAIN에 셀렉트 채인지 이벤트 발생시마다, 해당 데이터를 조해서 다시 뿌려주는..코딩

//그리드 셀렉션 체인지 이벤트 처리
private void bOARD_MAINDataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    //컨테이너에 데이터가 존재 한다면
    if (dsContext.EntityContainer != null)
    {
        //리스트의 내용을 지워놓고
        dsContext.BOARD_LISTs.Clear();
        //선택된 BOARD_MAIN을 일단 넣궁
        BOARD_MAIN bm = e.AddedItems.Cast<BOARD_MAIN>().FirstOrDefault();

        //BOARD_MAIN에 속해있는 BOARD_LIST만 조회
        dsContext.Load(dsContext.GetBoardListByBoardMainQuery(bm.BOARD_MAIN_IDX), LoadBehavior.RefreshCurrent, true);
    }
}

2-3. 인간같은 코딩
: 딱 필요할 때만 데이터를 서버에서 불러오고, 그 외에는 자체 해결~

수정 포인트 1

MainPage.xaml.cs

private void bOARD_MAINDataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{

    //선택된 BOARD_MAIN을 넣구
    BOARD_MAIN bm = e.AddedItems.Cast<BOARD_MAIN>().FirstOrDefault();

    //BOARD_MAIN에 속해있는 BOARD_LIST의 카운트가 0이거나, BOARD_MAIN이 변경되었을 경우
    if (bm.BoardLists.Count == 0 || bm.HasChanges == true)
    {

        //BOARD_MAIN_IDX가 들어있는 BOARD_LIST 조회
        dsContext.Load(dsContext.GetBoardListByBoardMainQuery(bm.BOARD_MAIN_IDX), LoadBehavior.RefreshCurrent, true);
    }
}


수정 포인트 2

MainPage.xaml

<sdk:DataGrid AutoGenerateColumns="False" Grid.Row="3"
              ItemsSource="{Binding SelectedItem.BoardLists, ElementName=bOARD_MAINDataGrid}"
              Name="bOARD_LISTDataGrid"
              RowDetailsVisibilityMode="VisibleWhenSelected">

바인딩 항목이 바뀌었다. 전에는 ItemsSource="{Binding Path=BOARD_LISTs}" 라는 항목을 바인딩 했었지만 지금은 BOARD_MAIN이 표시되는 그리드의 선택된 내용에 있는 BoardLists라는 항목을 바인딩 한다. 무슨 차이가 있을까??

지금부터 5분간 머리속으로 상상을 해보기 바란다. 그 차이를 찾는다면 왜 이게 인간같은 코딩인지 알 수 있을 것이다.


2. 열심히 로딩과 게으른 로딩(Eagerly loading and Lazy loading)
위와 같은 인간같은 코딩의 기본에는 열심히 로딩과 게으른 로딩(명시적 로딩과 비명시적 로딩 혹은 동기, 비동기 로딩)이란 베이스 기술이 필요하다.

Using DbContext in EF 4.1 Part 6: Loading Related Entities

http://blogs.msdn.com/b/adonet/archive/2011/01/31/using-dbcontext-in-ef-feature-ctp5-part-6-loading-related-entities.aspx

BOARD_MAIN은 이미 BOARD_LIST 중 어떤 넘이 자신을 찍었는지 알고 있다..다만 어떤 넘인지 표현 하려면, BOARD_LIST가 로딩이 되어야 가능하고, 로딩하는 시간과 방법에 따라 2가지로 구분을 한것이다. 좀 더 자세히 살펴 보면, BOARD_MAIN.cs 파일을 보면 아래와 같은 내용이 있었는데..

public virtual ObservableCollection<BOARD_LIST> BoardLists { get; set; }

여기서 virtual을 사용해준것이 게으른 로딩 방식을 사용하겠다는 뜻이다. 즉, 처음에 로딩할때 데이터 없이 그냥 로딩이 된다 하더라도, 나중에 데이터가 Context로 로딩이 되어 들어온다면 그 때 바인딩을 하겠다는 것이다.

3. 결과는 4회차 강좌나 5회차 강좌나 동일하다.
하지만, 그 내용적인 측면에서는 큰 의미를 가지고 있이며, 그걸 가지고 가기를 원한다. MS사의 개발 철학은 Decouple, Asynchronous, Loosely, Lazy 로 이동 중이며, Windows 8이 발표 되면서 정점을 찍을 것으로 생각된다.

Posted by MVP kaki104

댓글을 달아 주세요

이번에는 하나의 테이블을 추가해서 두개의 테이블을 서로 연결 시켜 놓고, CRUD를 하는 방법에 대해서 설명한다.

참고적으로.. 지금 개발하는 Silverlight 5, WCF RIA Service Support EF 4.1, SQL Server Compact 4.0을 이용한 예제 프로그램은 전세계에서 아마 이 프로그램이 유일할 듯하다.. 유사 프로그램도 없어서 하나 하나 찾아서 만드는게 쉽지 않다..그러나.. 끝까지 완성해서 실버라이트 공개 게시판이 자유롭게 만들어 지도록 하겠다...언넝 만들어야징;;(혼자 만들면 심심한데..ㅜㅜ 리플로 놀아주면 좋겠다는..쿨럭)

 
1. BOARD_LIST 테이블 추가

SL5_BOARD.Web -> Model Folder -> BOARD_LIST.cs 파일 추가

 using System;
using System.ComponentModel.DataAnnotations;

namespace SL5_BOARD.Web.Model
{
    public class BOARD_LIST
    {
        [Key]
        public int BOARD_LIST_IDX { get; set; }
        public string LIST_TITLE { get; set; }
        public string LIST_CONTENT { get; set; }
        public bool LIST_ATTACH_YN { get; set; }
        public int LIST_SEQ { get; set; }
        public int LIST_LEVEL { get; set; }
        public int LIST_VIEW_COUNT { get; set; }
        public string LIST_WRITER_NAME { get; set; }
        [DataType(DataType.Password)]  //패스워드를 저장할때 어떻게좀 해볼려고 써봤는데..잘 앙됨
        public string LIST_PASSWORD { get; set; }
        public string LIST_KIND { get; set; }
        public int LIST_COMPLETE_GB { get; set; }
        public bool LIST_OPEN_YN { get; set; }
        public int LIST_GOOD_COUNT { get; set; }
        public int LIST_PUBLIC_GB { get; set; }
        public DateTime REG_DT { get; set; }
        public int REG_IDX { get; set; }
        public DateTime? UPT_DT { get; set; }
        public int? UPT_IDX { get; set; }

        //여기가 중요!!
        //BOARD_MAIN 테이블과 연결 고리 음 일명 뽀링키가 되는데 형태가 오브젝트다
        //그리고 진짜 키 값은 바로 아래 필드에 존재하는데..사용 방법은 나중에

        public virtual BOARD_MAIN BoardMain { get; set; }
        public int BOARD_MAIN_IDX { get; set; }

        //생성자에서 초기값을 넣어 준다..귀찮으니 여기서 한번만 지정해 놓는다..int, bool형은 꼭 있어야 하더라는
        //이렇게 하는 것이 싫으면 위에 필드 타입에 ?를 붙여 주면 된다.

        public BOARD_LIST()
        {
            LIST_ATTACH_YN = false;
            LIST_SEQ = 0;
            LIST_LEVEL = 1;
            LIST_VIEW_COUNT = 0;
            LIST_COMPLETE_GB = 0;
            LIST_OPEN_YN = true;
            LIST_GOOD_COUNT = 0;
            LIST_PUBLIC_GB = 0;
        }
    }
}

2. BOARD_MAIN 테이블 수정

using System;
using System.Collections.ObjectModel;
using System.ComponentModel.DataAnnotations;

namespace SL5_BOARD.Web.Model
{
    public class BOARD_MAIN
    {
        [Key]
        public int BOARD_MAIN_IDX { get; set; }
        public string BOARD_NAME { get; set; }
        public string BOARD_TYPE { get; set; }
        public bool MEMBER_CHECK { get; set; }
        public string BOARD_DESC { get; set; }
        public string BOARD_STATE { get; set; }
        public DateTime REG_DT { get; set; }
        public int REG_IDX { get; set; }
        public DateTime? UPT_DT { get; set; }
        public int? UPT_IDX { get; set; }

        //BOARD_MAIN은 여러개의 BOARD_LIST를 가질 수 있다. 그래서 그런 연결관계에 대해서 메인에도 표시를
        //해주어야 한다. 역시 여기서도 옵저블컬렉션을 사용해서 세트를 만들었다.

        public virtual ObservableCollection<BOARD_LIST> BoardLists { get; set; }

        //BOARD_MAIN의 생성자
        public BOARD_MAIN()
        {
            BOARD_NAME = "신규 게시판";
            MEMBER_CHECK = false;
            //생성자에서 리스트 인스턴스 시켜준다.
            this.BoardLists = new ObservableCollection<BOARD_LIST>();
        }
    }
}

3. SL5_BOARD_DBCONTEXT 수정

using System.Data.Entity;
using System.Web;

namespace SL5_BOARD.Web.Model
{
    public class SL5_BOARD_DBCONTEXT : DbContext
    {
        public SL5_BOARD_DBCONTEXT()
            : base("SL5_BOARD")
        {
            if (HttpContext.Current == null)
            {
                Database.SetInitializer<SL5_BOARD_DBCONTEXT>(null);
            }
        }

        public DbSet<BOARD_MAIN> BOARD_MAINS { get; set; }

        //이넘 하나만 추가하면 된다.
        public DbSet<BOARD_LIST> BOARD_LISTS { get; set; }
    }
}

4. F6을 눌러서 빌드해 본다.

아마 100% 에러 날것이다.. 에..그 이유는 데이터 베이스에 내용이 변경되면 새로 만들어 주는 명령이 있는데..그 명령 EF4.1 버전에서 어떻게 사용하는지를 찾다가 포기했기 때문이다..ㅜㅜ 그래서 일단은 데이터베이스에 변경사항이 있을 경우 DB를 지워줘야 한다.(물론 수동이다..^^;;) 그래서 프로젝 끝나기 전까지는 웬만하면 데이터 마니 앙넣을려고 한다;;

SL5_BOARD.Web 프로젝트에 App_Data 폴더에 가서 SL5_BOARD.sdf 파일을 지우고 다시 F6을 눌러준다. 정상 적으로 빌드가 되었다면 다음으로 넘어간다.


5. SL5_BOARDDomainService.cs 파일 수정

#region BOARD_LIST
//기본적으로 전체 호출 하는 넘

public IQueryable<BOARD_LIST> GetBoardList()
{
    return this.DbContext.BOARD_LISTS;
}

//BOARD_MAIN_IDX 값을 받아서 조건에 만족하는 데이터만 반환, 참고로 LINQ 공부도 병행해야 한다..
public IQueryable<BOARD_LIST> GetBoardListByBoardMain(int BoardMainIDX)
{
    var query = from p in this.DbContext.BOARD_LISTS
                where p.BOARD_MAIN_IDX == BoardMainIDX
                orderby p.BOARD_LIST_IDX descending
                select p;

    return query.AsQueryable();
}

public void InsertBoardList(BOARD_LIST entity)
{
    DbEntityEntry<BOARD_LIST> entityEntry = this.DbContext.Entry(entity);
    if ((entityEntry.State != EntityState.Detached))
    {
        entityEntry.State = EntityState.Added;
    }
    else
    {
        this.DbContext.BOARD_LISTS.Add(entity);
    }
}

public void UpdateBoardList(BOARD_LIST entity)
{
    this.DbContext.BOARD_LISTS.AttachAsModified(entity, this.ChangeSet.GetOriginal(entity), this.DbContext);
}

public void DeleteBoardList(BOARD_LIST entity)
{
    DbEntityEntry<BOARD_LIST> entityEntry = this.DbContext.Entry(entity);
    if ((entityEntry.State != EntityState.Deleted))
    {
        entityEntry.State = EntityState.Deleted;
    }
    else
    {
        this.DbContext.BOARD_LISTS.Attach(entity);
        this.DbContext.BOARD_LISTS.Remove(entity);
    }
}
#endregion

수정 후 F6눌러서 컴파일을 꼭 해준다.


6. SL5_BOARD 프로젝트로 넘어간다.

MainPage.xaml의 디자인을 변경한다.



화면 구성은 대충 이정도 쯤인데.. 화면 구성만 바뀐것이 아니라 내부에 xaml단의 코딩이 변경되었다.

중요 변경사항은..riacontrol을 삭제, 그리드가 LayoutRoot의 DataContext에 있는 데이터를 바인딩 하도록 변경 되었다.

MainPage.xaml의 전체 소스다. 일단 지금은 타이틀리 커플드로 작업하고 차 후에 MVVM모델로 변경한다.

<UserControl x:Class="SL5_BOARD.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d" xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
    xmlns:my="clr-namespace:SL5_BOARD.Web.Model"
    xmlns:my1="clr-namespace:SL5_BOARD.Web.DomainService"
    d:DesignHeight="300" d:DesignWidth="400" Loaded="UserControl_Loaded">

    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="94*" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="148*" />
        </Grid.RowDefinitions>
       
        <sdk:DataGrid AutoGenerateColumns="False"
                      ItemsSource="{Binding Path=BOARD_MAINs}"
                      Name="bOARD_MAINDataGrid"
                      RowDetailsVisibilityMode="VisibleWhenSelected"
                      Grid.Row="1" SelectionChanged="bOARD_MAINDataGrid_SelectionChanged">
            <sdk:DataGrid.Columns>
                <sdk:DataGridTextColumn x:Name="bOARD_MAIN_IDXColumn" Binding="{Binding Path=BOARD_MAIN_IDX, Mode=OneWay}" Header="BOARD MAIN IDX" IsReadOnly="True" Width="SizeToHeader" />
                <sdk:DataGridTextColumn x:Name="bOARD_NAMEColumn" Binding="{Binding Path=BOARD_NAME}" Header="BOARD NAME" Width="SizeToHeader" />
                <sdk:DataGridTextColumn x:Name="bOARD_TYPEColumn" Binding="{Binding Path=BOARD_TYPE}" Header="BOARD TYPE" Width="SizeToHeader" />
                <sdk:DataGridCheckBoxColumn x:Name="mEMBER_CHECKColumn" Binding="{Binding Path=MEMBER_CHECK}" Header="MEMBER CHECK" Width="SizeToHeader" />
                <sdk:DataGridTextColumn x:Name="bOARD_DESCColumn" Binding="{Binding Path=BOARD_DESC}" Header="BOARD DESC" Width="SizeToHeader" />
                <sdk:DataGridTextColumn x:Name="bOARD_STATEColumn" Binding="{Binding Path=BOARD_STATE}" Header="BOARD STATE" Width="SizeToHeader" />
                <sdk:DataGridTemplateColumn x:Name="rEG_DTColumn" Header="REG DT" Width="SizeToHeader">
                    <sdk:DataGridTemplateColumn.CellEditingTemplate>
                        <DataTemplate>
                            <sdk:DatePicker SelectedDate="{Binding Path=REG_DT, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" />
                        </DataTemplate>
                    </sdk:DataGridTemplateColumn.CellEditingTemplate>
                    <sdk:DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Path=REG_DT, StringFormat=\{0:d\}}" />
                        </DataTemplate>
                    </sdk:DataGridTemplateColumn.CellTemplate>
                </sdk:DataGridTemplateColumn>

                <sdk:DataGridTextColumn x:Name="rEG_IDXColumn" Binding="{Binding Path=REG_IDX}" Header="REG IDX" Width="SizeToHeader" />
                <sdk:DataGridTemplateColumn x:Name="uPT_DTColumn" Header="UPT DT" Width="SizeToHeader">
                    <sdk:DataGridTemplateColumn.CellEditingTemplate>
                        <DataTemplate>
                            <sdk:DatePicker SelectedDate="{Binding Path=UPT_DT, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" />
                        </DataTemplate>
                    </sdk:DataGridTemplateColumn.CellEditingTemplate>
                    <sdk:DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Path=UPT_DT, StringFormat=\{0:d\}}" />
                        </DataTemplate>
                    </sdk:DataGridTemplateColumn.CellTemplate>
                </sdk:DataGridTemplateColumn>
                <sdk:DataGridTextColumn x:Name="uPT_IDXColumn" Binding="{Binding Path=UPT_IDX}" Header="UPT IDX" Width="SizeToHeader" />
            </sdk:DataGrid.Columns>
        </sdk:DataGrid>
        <Button Content="Insert" Height="23" HorizontalAlignment="Left" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" Margin="97,0,0,0" />
        <Button Content="Update" Height="23" HorizontalAlignment="Left" Margin="178,0,0,0" Name="button2" VerticalAlignment="Top" Width="75" Click="button1_Click"/>
        <Button Content="Delete" Height="23" HorizontalAlignment="Left" Margin="259,0,0,0" Name="button3" VerticalAlignment="Top" Width="75" Click="button1_Click"/>

        <sdk:DataGrid AutoGenerateColumns="False" Grid.Row="3"
                      ItemsSource="{Binding Path=BOARD_LISTs}"
                      Name="bOARD_LISTDataGrid"
                      RowDetailsVisibilityMode="VisibleWhenSelected">
            <sdk:DataGrid.Columns>
                <sdk:DataGridTextColumn x:Name="bOARD_LIST_IDXColumn" Binding="{Binding Path=BOARD_LIST_IDX, Mode=OneWay}" Header="BOARD LIST IDX" IsReadOnly="True" Width="SizeToHeader" />
                <sdk:DataGridTextColumn x:Name="bOARD_MAIN_IDXColumn1" Binding="{Binding Path=BOARD_MAIN_IDX}" Header="BOARD MAIN IDX" Width="SizeToHeader" />
                <sdk:DataGridCheckBoxColumn x:Name="lIST_ATTACH_YNColumn" Binding="{Binding Path=LIST_ATTACH_YN}" Header="LIST ATTACH YN" Width="SizeToHeader" />
                <sdk:DataGridTextColumn x:Name="lIST_COMPLETE_GBColumn" Binding="{Binding Path=LIST_COMPLETE_GB}" Header="LIST COMPLETE GB" Width="SizeToHeader" />
                <sdk:DataGridTextColumn x:Name="lIST_CONTENTColumn" Binding="{Binding Path=LIST_CONTENT}" Header="LIST CONTENT" Width="SizeToHeader" />
                <sdk:DataGridTextColumn x:Name="lIST_GOOD_COUNTColumn" Binding="{Binding Path=LIST_GOOD_COUNT}" Header="LIST GOOD COUNT" Width="SizeToHeader" />
                <sdk:DataGridTextColumn x:Name="lIST_KINDColumn" Binding="{Binding Path=LIST_KIND}" Header="LIST KIND" Width="SizeToHeader" />
                <sdk:DataGridTextColumn x:Name="lIST_LEVELColumn" Binding="{Binding Path=LIST_LEVEL}" Header="LIST LEVEL" Width="SizeToHeader" />
                <sdk:DataGridCheckBoxColumn x:Name="lIST_OPEN_YNColumn" Binding="{Binding Path=LIST_OPEN_YN}" Header="LIST OPEN YN" Width="SizeToHeader" />
                <sdk:DataGridTextColumn x:Name="lIST_PASSWORDColumn" Binding="{Binding Path=LIST_PASSWORD}" Header="LIST PASSWORD" Width="SizeToHeader" />
                <sdk:DataGridTextColumn x:Name="lIST_PUBLIC_GBColumn" Binding="{Binding Path=LIST_PUBLIC_GB}" Header="LIST PUBLIC GB" Width="SizeToHeader" />
                <sdk:DataGridTextColumn x:Name="lIST_SEQColumn" Binding="{Binding Path=LIST_SEQ}" Header="LIST SEQ" Width="SizeToHeader" />
                <sdk:DataGridTextColumn x:Name="lIST_TITLEColumn" Binding="{Binding Path=LIST_TITLE}" Header="LIST TITLE" Width="SizeToHeader" />
                <sdk:DataGridTextColumn x:Name="lIST_VIEW_COUNTColumn" Binding="{Binding Path=LIST_VIEW_COUNT}" Header="LIST VIEW COUNT" Width="SizeToHeader" />
                <sdk:DataGridTextColumn x:Name="lIST_WRITER_NAMEColumn" Binding="{Binding Path=LIST_WRITER_NAME}" Header="LIST WRITER NAME" Width="SizeToHeader" />
                <sdk:DataGridTemplateColumn x:Name="rEG_DTColumn1" Header="REG DT" Width="SizeToHeader">
                    <sdk:DataGridTemplateColumn.CellEditingTemplate>
                        <DataTemplate>
                            <sdk:DatePicker SelectedDate="{Binding Path=REG_DT, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" />
                        </DataTemplate>
                    </sdk:DataGridTemplateColumn.CellEditingTemplate>
                    <sdk:DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Path=REG_DT, StringFormat=\{0:d\}}" />
                        </DataTemplate>
                    </sdk:DataGridTemplateColumn.CellTemplate>
                </sdk:DataGridTemplateColumn>
                <sdk:DataGridTextColumn x:Name="rEG_IDXColumn1" Binding="{Binding Path=REG_IDX}" Header="REG IDX" Width="SizeToHeader" />
                <sdk:DataGridTemplateColumn x:Name="uPT_DTColumn1" Header="UPT DT" Width="SizeToHeader">
                    <sdk:DataGridTemplateColumn.CellEditingTemplate>
                        <DataTemplate>
                            <sdk:DatePicker SelectedDate="{Binding Path=UPT_DT, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true, TargetNullValue=''}" />
                        </DataTemplate>
                    </sdk:DataGridTemplateColumn.CellEditingTemplate>
                    <sdk:DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Path=UPT_DT, StringFormat=\{0:d\}}" />
                        </DataTemplate>
                    </sdk:DataGridTemplateColumn.CellTemplate>
                </sdk:DataGridTemplateColumn>
                <sdk:DataGridTextColumn x:Name="uPT_IDXColumn1" Binding="{Binding Path=UPT_IDX}" Header="UPT IDX" Width="SizeToHeader" />
            </sdk:DataGrid.Columns>
        </sdk:DataGrid>
        <TextBlock HorizontalAlignment="Left" Name="textBlock1" Text="BOARD MAIN :" VerticalAlignment="Center" Margin="8,4,0,3" />
        <Button Content="Insert List" Height="23" HorizontalAlignment="Left" Margin="97,6,0,0" Name="button4" VerticalAlignment="Top" Width="75" Grid.Row="2" Click="button4_Click" />
        <Button Content="Update List" Height="23" HorizontalAlignment="Left" Margin="178,6,0,0" Name="button5" VerticalAlignment="Top" Width="75" Grid.Row="2"  Click="button4_Click"/>
        <Button Content="Delete List" Height="23" HorizontalAlignment="Left" Margin="259,6,0,0" Name="button6" VerticalAlignment="Top" Width="75" Grid.Row="2"  Click="button4_Click"/>
        <TextBlock HorizontalAlignment="Left" Margin="8,10,0,9" Name="textBlock2" Text="BOARD LIST :" VerticalAlignment="Center" Grid.Row="2" />
    </Grid>
</UserControl>


7. MainPage.xaml.cs 전체

using System;
using System.Linq;
using System.ServiceModel.DomainServices.Client;
using System.Windows;
using System.Windows.Controls;
using SL5_BOARD.Web.DomainService;
using SL5_BOARD.Web.Model;

namespace SL5_BOARD
{
    public partial class MainPage : UserControl
    {
        //도메인 서비스를 사용하기 위한 변수 선언
        SL5_BOARDDomainContext dsContext;
        
        public MainPage()
        {
            InitializeComponent();

            //도메인 서비스 인스턴스
            dsContext = new SL5_BOARDDomainContext();
            //LayoutRoot.DataContext에 바인딩..이렇게 하면 하위 컨트롤들의 DataContext에도 모두 함께 바인딩 됨
            LayoutRoot.DataContext = dsContext;
        }

        //BOARD_MAIN INSERT, UPDATE, DELETE
        private void button1_Click(object sender, RoutedEventArgs e)
        {
            Button btn = sender as Button;
            switch (btn.Content.ToString())
            {
                case "Insert":
                    //riacontrol을 빼고 심플하게 정리
                    BOARD_MAIN bm = new BOARD_MAIN();
                    bm.REG_DT = DateTime.Now;
                    bm.REG_IDX = -1;
                    dsContext.BOARD_MAINs.Add(bm);
                    dsContext.SubmitChanges();
                    break;
                case "Update":
                    dsContext.SubmitChanges();
                    break;
                case "Delete":
                    //그리드에 선택된 내용 확인
                    if ((bOARD_MAINDataGrid.SelectedItem as BOARD_MAIN) != null)
                    {
                        dsContext.BOARD_MAINs.Remove(bOARD_MAINDataGrid.SelectedItem as BOARD_MAIN);
                        dsContext.SubmitChanges();
                    }
                    break;
            }
        }

        //BOARD_LIST INSERT, UPDATE, DELETE
        private void button4_Click(object sender, RoutedEventArgs e)
        {
            Button btn = sender as Button;
            switch (btn.Content.ToString())
            {
                case "Insert List":
                    if ((bOARD_MAINDataGrid.SelectedItem as BOARD_MAIN) != null)
                    {
                        BOARD_LIST bl = new BOARD_LIST();
                        dsContext.BOARD_LISTs.Add(bl);
                        bl.REG_DT = DateTime.Now;
                        bl.REG_IDX = -1;

                        //선택된 BOARD_MAIN을 여기다가 쑤셔 넣은 후 저장
                        bl.BoardMain = bOARD_MAINDataGrid.SelectedItem as BOARD_MAIN;

                        dsContext.SubmitChanges();
                    }
                    break;
                case "Update List":
                    dsContext.SubmitChanges();
                    break;
                case "Delete List":
                    if (bOARD_LISTDataGrid.SelectedItem as BOARD_LIST != null)
                    {
                        dsContext.BOARD_LISTs.Remove(bOARD_LISTDataGrid.SelectedItem as BOARD_LIST);
                        dsContext.SubmitChanges();
                    }
                    break;
            }
        }

        //화면 로딩 후 BOARD_MAIN 전체 조회
        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            dsContext.Load(dsContext.GetBoardMainQuery(), LoadBehavior.RefreshCurrent, true);
        }

        //그리드 셀렉션 체인지 이벤트 처리
        private void bOARD_MAINDataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            //컨테이너에 데이터가 존재 한다면
            if (dsContext.EntityContainer != null)
            {
                //리스트의 내용을 지워놓고
                dsContext.BOARD_LISTs.Clear();
                //선택된 BOARD_MAIN을 일단 넣궁
                BOARD_MAIN bm = e.AddedItems.Cast<BOARD_MAIN>().FirstOrDefault();
                //BOARD_MAIN에 속해있는 BOARD_LIST만 조회
                dsContext.Load(dsContext.GetBoardListByBoardMainQuery(bm.BOARD_MAIN_IDX), LoadBehavior.RefreshCurrent, true);
            }
        }
    }
}


8. 실행 모습



음..물론 Update, Delete 기능도 잘 동작한다.


9. 나머지 테이블도...
 후딱 만들고 본격적으로 작업에 들어가야 겠다..그런데 역시 Code First라 테이블 만들기가 매우 귀찮은..쿨럭..그냥 Model First에서 모델만들고 한번에 후루룩 만들면 더 쉬울건데..

전체 길이가 너무 길어져서..보기가 좀 불편하지만..거의 모든 소스를 올려 놓은 것이니 다시 잘 만들어 보자. 소스 요청은 리플로 이메일을 남겨주면 된다.

Posted by MVP kaki104

댓글을 달아 주세요

2회에 이어 이제 본격적으로 시작을 해보자. 테이블 명세서는 1회에 있는 내용을 사용해서 만들 것이니 참고를 하면 돼고, 이번에는 Code First란 무엇인지 먼저 좀 알아보고, Code First를 이용해서 클래스를 만들고 데이터베이스를 만드는 과정을 하나 하나 보도록 하겠다.

1. 목표

1회에 보면 귀차니즘으로 인해 Model First로 작업을 하겠다고 했었는데..어쩔 수 없이 Code First로 작업을 해야한다. 이건 사연이 좀 있는데 엠에스에서 얼마전 EF(Entity Framework) 4.2를 정식 버전 배포를 했었는데.. 지금 사용하고 있는 EF버전은 4.1이다. 그러다 보니 Package형태로 배포가 된것인 듯하고, 또한 오직 Code First만을 지원한다....(이걸 알기 위해 몇시간 삽질을 했다는..)

음..아마도 다음에 EF4.5정도가 나오면 아마 두개가 합해져서 나오지 않을까 생각하며, 이 강좌(게시판 만들기)에서는 몇가지만 가지고 가면 될 것이다.

1-1. Code First 사용 방법

1-2. SQL Server Compact 4.0 - Streamlined Database의 개념 및 사용법

1-3. WCF RIA Service Support EF4.1 사용 방법

2. 강좌 관련 사이트 정리

ado.net team blog
http://blogs.msdn.com/b/adonet/

WCF RIA Services Support for EF 4.1 (and EF Code-First)
http://varunpuranik.wordpress.com/

RIA Services EF Code First Support
http://jeffhandley.com/

자세한 환경설정은 강좌 2번을 참고하고, 그렇게 해두 앙대면, 리플로 알려 주면 해결 방법을 찾아보겠다.

3. 만들기 시작
일단 BOARD_MAN이란 이름의 테이블 한개만 가지고 어떻게 만드는 것인지에 대한 내용을 정리하도록 하겠다.

3-1. 폴더 추가

SL5_BOARD.Web

DomainService, Model 2개의 폴더 추가

3-2. BOARD_MAIN 작업

먼저 Model폴더에 클래스 추가 -> 이름 : BOARD_MAIN.cs

//Key를 잡기 위해서 추가함
using System.ComponentModel.DataAnnotations; 

namespace SL5_BOARD.Web.Model
{
    public class BOARD_MAIN
    {
        [Key]
        public int BOARD_MAIN_IDX { get; set; }
        public string BOARD_NAME { get; set; }
        public string BOARD_TYPE { get; set; }
        public bool MEMBER_CHECK { get; set; }
        public string BOARD_DESC { get; set; }
        public string BOARD_STATE { get; set; }
        public DateTime REG_DT { get; set; }
        public int REG_IDX { get; set; }
        public DateTime? UPT_DT { get; set; }          //Null허용 DateTime은 반드시 필요, String은 그냥 둬두댐
        public int? UPT_IDX { get; set; }                  //Null허용
    }
}

음..정확하게 할려면 문자열의 길이도 정하고 해야겠지만 생략한다. 이렇게 하면 하나의 레코드를 정의 한 것이다. 음..어려운 것 없다는..ㅋㅋ

주의 할 점은 클래스에 반드시 하나이상의 Key필드가 존재 해야 한다는 것인데, 예를 들어 처음 필드명이 ID로 끝나는 단어를 가지고 있다면 그 필드는 자동을 Key로 인식이 되고, ID가 아니면 명시적으로 [Key]를 붙여 주어야 한다.

모든 필드에 값을 넣을 수 없을 때 Null허용 필드를 만들기 위해서는 타입뒤에 ?를 붙여서 Null허용을 표시한다. (DateTime필드는 꼭 붙여주어야 한다.)

3-3. Database 작업

using System.Web;
using System.Data.Entity;

namespace SL5_BOARD.Web.Model
{
    //맨뒤에 DbContext가 바로 이 클래스를 Db로 인식시키는 넘이다.
    public class SL5_BOARD_DBCONTEXT : DbContext
    {
        //생성자에서.. : base("SL5_BOARD") 라는 부분이 생략되면 로컬에 있는 sqlexpress DB를 사용하는 걸로 간주한다.
        //여기서는 Web.config에 있는 SL5_BOARD라는 ConnectionString을 사용하도록 지정되어 있다.
        public SL5_BOARD_DBCONTEXT()
            : base("SL5_BOARD")
        {
            //기존 Code First에 없던 내용으로 WCF RIA Service에서만 추가된 내용으로 디자인 타임에서
            //Database 생성을 하지 않도록 하기 위한 내용이다.
            if (HttpContext.Current == null)
            {
                //원래 여기도 맨뒤에 길게 꼬리가 붙어있는데 WCF RIA Service에서는 null로 처리를 한다.
                Database.SetInitializer<SL5_BOARD_DBCONTEXT>(null);
            }
        }
        //Table 객체
        public DbSet<BOARD_MAIN> BOARD_MAINS { get; set; }
    }
}


먼저 Model폴더에 클래스 추가 -> 이름 : SL5_BOARD_DBCONTEXT.cs음..그럼 일단 데이터베이스 만들고, 테이블 만드는 것 까지는 했다. 위해서 이야기를 했지만 Code First는 기본으로는 로컬 컴퓨터에 sqlexpress를 기본 DB로 생각하고 있지만.. 강좌에서는 Compact DB를 사용하기로 했기 때문에 Web.config를 설정해야한다. (이것도 30분정도 삽질해서 찾아낸 내용이라는..;; 뭐든지 쉬운것은 하나도 없다. )

3-4. Web.config

<connectionStrings>
  <add name="SL5_BOARD"
       providerName="System.Data.SqlServerCe.4.0"
       connectionString="Data Source=|DataDirectory|\SL5_BOARD.sdf"/>   
</connectionStrings>

딱 위의 문장이다..하지만, 그냥 아..그렇구나하고 넘어가면 에러 하나가 무지하게 괴롭힐 것이다. 왜일까? 우리는 DB를 웹서버 바로 아래 놓을 것이기 때문에 상대 경로를 적어 주어야 한다. 요기서 상대경로 지정 방법을 알고 있다면 패스하고 다음으로 넘어가도 좋다.

3-5. ASP.NET Folder추가
SL5_BOARD.Web -> 오른쪽 마우스 클릭 -> Add -> Add ASP.NET Folder -> App_Data
이렇게 지정한다. 그럼 SL5_BOARD.Web 프로젝트에 App_Data라는 폴더가 추가되고, 그 폴더를 지칭하는 문자열이 |DataDirectory| 이다 왼쪽 오른쪽에 |문자가 존재한다.

3-6. Database File 추가
않한다. 패스~ 그냥 폴더만 만들어 놓는다;;

3-7. Domain Service추가
DomainService 폴더에 SL5_BOARDDomainService.cs라는 클래스 추가

//추가
using System.ServiceModel.DomainServices.Hosting;
using System.ServiceModel.DomainServices.EntityFramework;
using SL5_BOARD.Web.Model;
using System.Data.Entity.Infrastructure;
using System.Data;

namespace SL5_BOARD.Web.DomainService
{
    //이번에 새로 나온 내용~
    [EnableClientAccess]
    //                                                        이넘두 새로 나온 내용
    public class SL5_BOARDDomainService : DbDomainService<SL5_BOARD_DBCONTEXT>
    {
        //기본 조회
        public IQueryable<BOARD_MAIN> GetBoardMain()
        {
            return this.DbContext.BOARD_MAINS;
        }
        //Insert 작업 처리부
        public void InsertBoardMain(BOARD_MAIN entity)
        {
            DbEntityEntry<BOARD_MAIN> entityEntry = this.DbContext.Entry(entity);
            if ((entityEntry.State != EntityState.Detached))
            {
                entityEntry.State = EntityState.Added;
            }
            else
            {
                this.DbContext.BOARD_MAINS.Add(entity);
            }
        }
        //Update 작업 처리부
        public void UpdateBoardMain(BOARD_MAIN entity)
        {
            this.DbContext.BOARD_MAINS.AttachAsModified(entity, this.ChangeSet.GetOriginal(entity), this.DbContext);
        }
        //Delete 작업 처리부
        public void DeleteBoardMain(BOARD_MAIN entity)
        {
            DbEntityEntry<BOARD_MAIN> entityEntry = this.DbContext.Entry(entity);
            if ((entityEntry.State != EntityState.Deleted))
            {
                entityEntry.State = EntityState.Deleted;
            }
            else
            {
                this.DbContext.BOARD_MAINS.Attach(entity);
                this.DbContext.BOARD_MAINS.Remove(entity);
            }
        }
    }
}

Select하는 부분은 WCF RIA Serivce 4.0과 흡사 하지만, Insert, Update, Delete부분은 큰 차이가 있는데, 그것은 4.0에서는 레코드를 Object로 처리를 하고, 5.0은 엔티티로 처리를 한다는 것이다. 에..그게 정확하게 무슨 의미냐구 반문을 해도 딱히 한 단어로 설명을 하기는 어렵고.. 디버그나 앞으로 작업을 하면서 어떤 것인지 직접 느껴야 할 것이다. 자세한 설명은 다음으로..일단 미룬다..

3-8. 빌드를 하고 실행해보자
빈화면이 이쁘게 잘뜨고 에러도 없으면 일단 성공이다. 에러가 Workspace를 불러 올수 없다는 그런 오류가 뜨면, 어딘가가 틀렸을 것이니 다시 차근 차근 검사를 하기 바란다. 그럼 이제 실버라이트로 넘어가 보자

3-9. SL5_BOARD 프로젝트 -> MainPage.xaml
화면 왼쪽 사이드 메뉴 중에 Data Sources라는 텝이 보일 것이다. (SL4 WCF RIA 프로그램 강좌 참고) 눌러 보면 SL5_BOARDDomainContext라는 내용이 보이면서 BOARD_MAIN이란 항목이 표시 된다.(처음에 뜰때 시간이 걸리니 약간 인내하자)
BOARD_MAIN을 드래그해서 MainPage.xaml 하면에 드롭하면 자동으로 코드가 생성된다. 그리고 실행해보자. 한번에 여기까지 성공을 하면 당신은 천재 일지도 모른다..(여기까지 작업하는데 3시간 정도 걸렸었다;;)

비록 보이는건(그리드 헤더는 보인다) 없지만, 오류없이 화면만 잘 떠도 성공적인 것이다. 그런데, 궁금하지 않나? 과연 데이터베이스는? 테이블은? 데이터는? 아까 우린 데이터베이스를 만든적도 없고, 그냥 연결문자열만 작성하고 넘어왔었다. 그런데 어떻게 화면에 내용이 나올까??

WCF RIA Service support EF4.1 Code First 에서는 SL5_BOARD_DBCONTEXT 넘이 인스턴스 될때 모든 작업을 백그라운드로 처리를 한다. 데이터 베이스를 만들고, 테이블을 만들고, 머 또 다른 할일있으면 하는.. 그럼 이제 아까 SL5_BOARD.Web 프로젝트에 만들어 놓은 App_Data폴더를 열어보자..(탐색기로 찾아가자) 아마 깜짝 놀랄지도..

VS2010 화면 왼쪽 사이드 메뉴 중에 Server Explorer 텝을 클릭 -> Data Connections에서 오른쪽 마우스 클릭 -> Add Connection 을 선택해서 새로 생긴 파일을 선택해서 내용을 확인해보자. 테이블도 이쁘게 만들어져 있을 것이다.


3-10. 추가 작업(CRUD)
SL5_BOARD 프로젝트 -> Add Reference -> System.Windows.Data 추가

3-11. MainPage.xaml 화면 개선 작업

화면에 버튼을 3개를 추가하고 더블 클릭해서 이벤트를 연결해 준다.

3-12. MainPage.xaml.cs

using SL5_BOARD.Web.Model;

//3개의 버튼의 클릭 이벤트를 모두 여기로
private void button1_Click(object sender, RoutedEventArgs e)
{
    Button btn = sender as Button;
    switch (btn.Content.ToString())
    {
        case "Insert":
            //DTO객체를 만들고
            BOARD_MAIN bm = new BOARD_MAIN();

            //날짜를 입력(날짜를 앙넣어주면 0001/01/01로 초기값이 들어가는데 오류남)
            bm.REG_DT = DateTime.Now;
            bm.REG_IDX = -1;

            //일단 새로 만든걸 추가하고
            bOARD_MAINDomainDataSource.DataView.Add(bm);

            //바로 서브밋 - 서브밋을 하자마자 ID가 부여되어서 바로 보임
            bOARD_MAINDomainDataSource.DomainContext.SubmitChanges();
            break;
        case "Update":
            //서브밋
            bOARD_MAINDomainDataSource.DomainContext.SubmitChanges();
            break;
        case "Delete":
            //선택된 아이템이 있을 경우
            if (bOARD_MAINDomainDataSource.DataView.CurrentItem != null)
            {
                //선택된 아이템 삭제
                bOARD_MAINDomainDataSource.DataView.Remove(bOARD_MAINDomainDataSource.DataView.CurrentItem);
                //서브밋
                bOARD_MAINDomainDataSource.DomainContext.SubmitChanges();
            }
            break;
    }
}


3-13. 일단 여기까지만 하도록 하자..화면을 실행해서 Insert버튼도 눌러보고, Update버튼도 눌러보고..

DB에 저장대고 삭제되는 과정들을 쭈욱 한번씩 보기 바란다. 그리고, 소스는 당분간 리플로 요청한 분들에 한해서만 보내 주는 방향으로 하겠다. 같이 해야 가치가 있다는.. 굿굿한 신념으로..함께 차근 차근 만들면서 진행해야 실력이 는다.

에러도 먼저 맞은 넘이 낳고, 일찍 에러나는 코딩이 오래간다!

그럼


 

 

Posted by MVP kaki104

댓글을 달아 주세요

처음이니 간단하게 프로젝트만 만들고 자야쥐..냐하하..;; 하지만!! 비록 처음이기는 하지만 매우 중요한 부분이 나오니 찬찬히 보아야 한다는..

VS2010 실행

File -> New Project

폴더 정하고, 이름 정하고 OK

요기 중요한 부분! 꼭 Enable WCF RIA Services 체크~, 그리고 OK.
처음 나오는 깨끗한 네모상자~ 음.. 아직 이 상자에 볼일은 없으니..일단 SL5_BOARD.Web -> SL5_BOARDTestPage.aspx 더블 클릭해서 열고(묻지 말고 그냥 열어주삼 할일이 있응께)

NuGet Packages를 선택..

* NuGet Packages란
NuGet is a free, open source developer focused package management system for the .NET platform intent on simplifying the process of incorporating third party libraries into a .NET application during development
이런 설명이..공짜 오픈 소스이구 닷넷 개발자를 위한..머 대략 그런 내용이니 읽고 싶다면..
http://nuget.codeplex.com/
위의 주소를 클릭.. 참 그리고 엠에스사가 요즘 여기를 통해서 이것저것 테스트 하고 있다는..가져다가 쓰기도 잘쓰고..엠에스랑 무슨 관계인지는 알 수 없음;;

* WCF RIA Services Support for EF 4.1 (and EF Code-First)
WCF 서비스 중에서 최고로 편하고, 사용하기 좋은 WCF RIA 서비스가 그동안 SP2까지 나왔지만, 여전히 EF4.1을 지원하지 앙아서 WCF RIA Service가 나오기를 손꼽아서 기다리던 중 얼마전 한 포스트에 올라온 글을 보고 NuGet Package형태로 배포가 되고 있다는 사실을 알았다. (http://varunpuranik.wordpress.com/2011/06/29/wcf-ria-services-support-for-ef-4-1-and-ef-code-first/)
중요한 2가지가 업데이트가 되었다는데,
1) DbContext base API 제공
2) Code-First support가 핵심이다.
더 자세한 정보는 ADO.NET team blog 요기서 알아보라구 하는..그래서, 이제 DbContextDbDomainService를 사용할 수 있게 되었고, Tool을 통해서 DbDomainService용 코드 생성을 지원한다고 한다.(코드 퍼스트에서는 툴을 이용할 일이 없을 듯하지만..)

**DB만드는 방법 3가지
1)) Database First : 테이블만들고, 엔티티 모델만들고, 클래스 생성해서 사용
2)) Model First : 엔티티 모델 만들고, 테이블만들고, 클래스 생성해서 사용
3)) Code First : 클래스 만들고 실행하면 테이블 만들어짐 클래스만 가지고 놀면 됨
-> 3가지 방식 중 자신에게 맞는 방식을 선택해서 만들면 된다고하는.. 어떤 방식으로 하던간에 EF4.1의 기능을 잘 사용할 수 있다.
그래서 새로나온 WCF RIA Service를 이용하기 위해서는 WCF RIA Services V1.0 RTM 버전과, SP1 or SP2 가 인스톨되어 있어야지만 한단다.(이전 강좌나 구글에서 찾으면 나온다)
그리고 마지막으로 Microsoft.ServiceModel.DomainServices.EntityFramework.dll 이 필요한데 이넘을 NuGet Package에서 다운 받아서 설치를 할 수 있는 것이다. (NuGet Package는 프로젝트 단위로 설치되기 때문에 새 프로젝트를 만들면 또 설치해줘야한다.)
http://nuget.org/List/Packages/RIAServices.EntityFramework
위의 링크가 설치할 수 있는 곳이라구 하는데 가보면

PM> Install-Package RIAServices.entityFramework라구 써있구 다운로드 링크가 업다;; 그래서, 저 문장을 처서 설치할 수 도 있고 좀 편하게 그냥 NuGet Package검색에서 찾아서 설치할수도 있다.
그게 좀전에 이야기했던 Manage NuGet Packages 메뉴라는..

위의 화면 처럼 찾아서 Install버튼을 클릭한다.(만으니까 wcf ria라고 검색해서 찾아야한다)
설치가 완료되면 녹색 체크 마크가 표시된다. 그럼 이제 Close버튼을 눌러 닫는다. 그럼 뭐가 변했는지 찾아보자

위에 사진에 가운데를 보면 EntityFramework버전이 4.1.10331.0으로 표시되는 것을 볼 수있다. 여기까지하고 실행해보면 머 빈 화면이 댕그러니 뜨기는 하지만..뭔가 뿌듯하다..음음..(나만 그런가;; 시작이 반이라니까..;;)

다음에는 클래스를 만들어서 테이블을 만들도록 하겠다.(모델 퍼스트로 그냥. 해야겠당..냐하하..코드 퍼스트는 귀차니즘이..쿨럭)


 

 

 

 

 

Posted by MVP kaki104

댓글을 달아 주세요

1. 바로 어제 드디어 기다리고 기다리던 WCF RIA Services Support for EF 4.1 (and EF Code-First)이 나온것을 알게 되었습니다.

http://varunpuranik.wordpress.com/2011/06/29/wcf-ria-services-support-for-ef-4-1-and-ef-code-first/

아직 정식 배포 버전은 아니고 NuGet Package 형태로 제공되고 있지만, 테스트를 해본 봐로는 서버 단에서는 스트림라인드 데이터 베이스, Code-First로 작업을 하고, 클라이언트에서는 WCF RIA 4버전과 사용방법은 동일 한것으로 보였습니다.

좀더 자세한건 일단 만들어 보면 알 수 있겠죠.

그래서 이번 기회에 WCF RIA를 이용한 스트림라인드로만 구성되는 실버라이트 게시판을 만들어서 공개를 할까 합니다.

사용한 기술은 아래와 같습니다.

2. 공개 게시판

MS SQL Server Compact 4.0 : 데이터베이스

Silverlight 5 beta - MVVM 적용 : 클라이언트 기술

WCF RIA Services Support for EF 4.1 (and EF Code-First) : 네트워크 기술

MEF : 컨테이너 기술?

LINQ : 데이터 조작

컨트롤 : RadControls for Silverlight Q1 2011 사용

DataGrid로 만드는 것은 해보지 앙아서..ㅜㅜ

Prism4 : 될수 있으면 적용을 하고 싶기는 한데..어떻게 될지는 모르겠네요 저도 공부를 해야하는 분야라 - 적용을 한다면 MEF Container를 사용 할려고 합니다.

3. 프로젝트라고 거창해 보이기는 한데..그냥 지난 강좌처럼 쪼금씩 몇 회에 걸쳐서 지속적으로 하나하나 적어 볼려고 합니다. 중간 중간 소스도 올려소 직접 실행 해 보실 수 있도록 할것이며, 여기에서 만든 게시판을 가지고 진짜 사이트에 배포하는 것 까지 계획을 잡고 있습니다. 계획이 조금 거창해 보이기는 하지만..머 시간만 허락한다면...흐흐;;

4. 기본적인 테이블 구조는 제가 전에 만들었던 게시판 테이블 구조를 사용하면 되는데.. 목표는 제로보드 처럼 범용 적으로 사용 할 수 있는 게시판이 목표인데..어떤 기능이 필요한지.. 잘 모르겠네요.. 혹시 조언이 있으면 좀 부탁드립니다.

5. 구인 : 블랜드 디자인 해주실분 구합니다(무료봉사 강요예정... 나중에 저녁 정도는..). 음음..그래도 명세기 실버라이트 게시판인데 애니메이션 하나 들어가지 앙는 재미없는 게시판을 만들고 싶지는 앙네요..

6. 생각 중인 게시판 기능

6-1. 게시판 목록 조회/글쓰기/수정/삭제/리플

6-2. 로그인/로그아웃/회원가입

6-3. 관리자페이지/메뉴추가삭제/회원관리(회원목록조회/찾기/탈퇴)

헉 일단 이정도만해두 페이지 수가 좀 되는 군요.. 디자이너분이 구해지면 스토리 보드를 한번 그려봐야겠네요..일단은 테이블 정리하고 Code-First로 작업 할 것이니 클래스를 만들어야겠네요

생각처럼 멋진 게시판이 만들어 지면 좋겠내요..

그럼


 

Posted by MVP kaki104

댓글을 달아 주세요