.Net Ria Service 와 Entities 그리고 Stored Procedure 하다가 생긴일..

RIA 2010. 7. 15. 21:04 Posted by 알 수 없는 사용자
특별한 포스팅이 아니라 잠깐 고생했었던 이야기를 적어보려고 합니다.

이번 프로젝트에서 엔티티와 리아서비스를 주로 사용하고 있는데요.
리아서비스 편하긴 정말 많이 편하더군요. 
복잡한 쿼리가 아닌 이상은 리아서비스를 + 링크(linq) 를 이용해서 바로바로 처리했었습니다.

거의 대부분 복잡하지가 않아서 무난하게 작업중이였는데요.
오늘 복잡한 부분을 처리해야될 부분이 있어서
프로시저를 사용하게 되었습니다.

하나의 특정한 테이블이 아니라 여러개의 테이블에서 데이터를 가져와서 가공한터라..
기본키가 없었습니다.

그리고 사실 디비를 잘 알지도 못하구요.

프로시저를 추가해주니 엔티티가 자동으로 생기지 않는겁니다. -ㅁ-;
Complex types(으)로 엔터티를 만들어주었습니다.

절차는 아래와 같습니다.


우선 프로시저를 .edmx 파일을 열어서 추가 합니다.


추가한 프로시저를 우클릭하여 "Add function import" 해줍니다.


위와 같은 창이 뜨면 만들어진 entities 를 이용할 수도 있지만 저는 " complex" 를 선택하여 자동으로 만들어 주었습니다.



위와 같이 complex types 폴더에 자동으로 "sp_GetTeachersTimerTable_Result"가 만들어진 모습입니다.
프로시저 이름 + _Result 네요.

이렇게 하구 Domain service에 추가를 해줬습니다.
근데 기존에 Table Entities 와는 다르게 자동으로 코드가 생기지 않더군요.
수동으로 해줘야하는 모양입니다.

        public ObjectResult GetTimeTable(int teacherNo)
        {
            return this.ObjectContext.sp_GetTeachersTimeTable(teacherNo);
        }


그래서 손수 위와 같이 입력을 해주었습니다. 오류가 나더군요.
머 적어도 하나의 기본키는 있어야한다는 내용이였습니다..

select 로 가져온 결과값에 기본키를 지정할 수 있는 방법을 몰랐습니다.
수동으로 complex types entities 를 만져보고 해봤는데도 잘 안되더라구요.

코드단에서 한번 수정을 해보자 싶어서 .edmx.Designer.cs 파일을 열어보았습니다.
자동으로 만들어진 엔터티에 관한 내용들 사이에서 제가 원하던 

public partial class sp_GetTeachersTimeTable_Result : ComplexObject

클래스를 찾았습니다.
그곳에서 제일 만만한 속성을 골라잡아서 강제로 [Key] 를입력해주니깐 바로 해결이 되더군요.

        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
        [DataMemberAttribute()]
        [Key]
        public global::System.Int32 sid

        {

                     ...

         }

원래 이렇게 하는건지..
물론 다른 방법이 있겠지만..

어찌되었든 해결이 되어 포스팅 해봅니다.
안녕하세요. 지난 시간에는 jqGrid를 이용해서 리스트를 구현해봤습니다. 정말 맛보기였죠? :)
이번 시간은 실제 데이터베이스에서 데이터 조회, 페이징과 정렬부분을 다루도록 하겠습니다.

먼저 데이터베이스 생성

테이블 구조는 다음과 같습니다.

 컬럼명  데이터 타입
 dirId  int
 name  nvarchar(50)
 phone  nvarchar(50)
 email  nvarchar(50)
 speedDial  decimal(2,0)

그냥 기본세팅이죠^^;

엔터티 모델 클래스를 생성할 건데요, 자세히(?)를 원하신다면 이전 포스팅을 참고해주세요^^;
완료가 되면,


여기까지 잘 오셨죠? 저는 Entity Set Name을 TelDir에서 TelDirSet으로 변경하였습니다. 헷갈려서요^^;;

자. 이제는 본격적(?)으로 살펴볼까요? (어째.. 오늘도 맛보기일것 같은 분위기가 물~씬 풍기시죠? ㅡ,.ㅡ;)

페이징 기능을 달자

지난 뷰페이지에 pager란 id로 div 태그를 추가하겠습니다.

<div id="pager" class="scroll" style="text-align:center;"></div>

테이블 뒤에 추가하시면 됩니다.
그리고, 스크립트 부분도 수정해야겠죠?

    <script src="/Scripts/grid.locale-en.js" type="text/javascript"></script>
    <script type="text/javascript">
        $(function () {
            $("#list").jqGrid({
                url: '<%= Url.Action("EntityGridData", "Home") %>',
                datatype: 'json',
                mtype: 'POST',
                colNames: ['No', '이름', '전화번호', '이메일', '단축다이얼'],
                colModel: [
                  { name: 'dirId', index: 'dirId', width: 40, align: 'center' },
                  { name: 'name', index: 'name', width: 100, align: 'left' },
                  { name: 'phone', index: 'phone', width: 150, align: 'left' },
                  { name: 'email', index: 'email', width: 250, align: 'left' },
                  { name: 'speedDial', index: 'speedDial', width: 100, align: 'center'}],
                    pager: $('#pager'),
                emptyrecords: "Nothing to display",            
                rowNum: 3,
                rowList: [3, 10, 20, 50],
                sortname: 'dirId',
                sortorder: "desc",
                viewrecords: true,

                caption: '전화번호부'
            });
        });
    </script>

추가된 부분은 굵은글씨로 표시하였습니다. 일단, grid.locale-en.js를 추가해야되더라고요^^; 디폴트로 그냥 jqGrid 스크립트를 넣을때 추가하라고 하였는데, 제가 지난 포스팅때는 빠뜨렸죠.
이런 언어 스크립트 파일에는 페이징 관련한 디폴트 값들이 들어가 있습니다.

defaults:{
   recordtext:"View {0} - {1} of {2}",
   emptyrecords:"No records to view",
   loadtext:"Loading...",
   pgtext:"Page {0} of {1}"
  }


나머지 프로퍼티에 대한 설명을 드리자면,
pager는 위 이미지 보이시죠? ^^; 저렇게 레코드들을 이동할수 있게 해주는 페이징 바를 정의합니다.
저같은 경우는 $('#pager')로 jQuery 표현을 썼는데요, jqGrid의 wiki를 보니 '#pager', 'pager', jQuery('#pager') 세가지 경우가 모두 가능한데요. 앞에 두가지 방법을 추천한다네요. 흠. jQuery 변수가 내보내기, 가져오기 모듈을 이용할때 문제를 발생시킬수 있다고 합니다. 이 부분은 차츰(?) 찾아보도록 하죠;;

The definition of the pager in the grid can be done this way:pager : '#gridpager', pager : 'gridpager' or pager : jQuery('#gridpager'). All the three methods are valid, but I recommend to use the first or second one, since the jQuery variant causes problems when we try to use Exporting and Importing modules.

emptyrecords는 말 그대로 데이터가 없을 때 표현할 문구를 나타내고요,
rowNum은 페이지에서 보여줄 레코드 갯수,
rowList는 페이지 갯수를 선택할 수 있도록 하는 셀렉트박스의 옵션들,
sortname, sortorder는 각각 정렬할 컬럼과 정렬방식(오름차순, 내림차순),
viewrecords는 토탈 레코드의 수(위 이미지에서 View 1 -3 of 5)를 표현하는 것을 허용할 것인지 여부를 나타냅니다.

이제 뷰페이지는 완성이 되었고요, 컨트롤러 손봐야겠죠?
EntityGridData() 라는 이름의 액션메쏘드를 추가하겠습니다.

[HttpPost]
        public ActionResult EntityGridData(string sidx, string sord, int page, int rows)
        {
            // 데이터베이스 연결
            MvcDbEntities _db = new MvcDbEntities();

            // 페이징 변수 세팅
            int pageIndex = Convert.ToInt32(page) - 1;
            int pageSize = rows;    // 3
            int totalRecords = _db.TelDirSet.Count();
            int totalPages = (int)Math.Ceiling((float)totalRecords / (float)pageSize);

            // 데이터 조회(페이징&정렬)
            // sidx : dirId
            // sord : desc
            var dirs = _db.TelDirSet
                .OrderBy("it." + sidx + " " + sord)
                .Skip(pageIndex * pageSize)
                .Take(pageSize)
                .ToList();

            var jsonData = new
            {
                total = totalPages,
                page = page,
                records = totalRecords,
                rows = (
                  from dir in dirs
                  select new
                  {
                      i = dir.dirId,
                      cell = new string[] {
                          dir.dirId.ToString(), dir.name.ToString(), dir.phone.ToString(), dir.email.ToString(), dir.speedDial.ToString()                         
                      }
                  }).ToArray()
            };
            return Json(jsonData);
        }

궁금해 보이는 것이 없죠? ㅎㅎ
jqGrid가 EntityGridData를 호출할때 파라미터(sidx : dirId, sord : desc, page : 1, rows : 3)를 날립니다~~~
실행을 해보면,


너무 간단하게 페이징 기능이 완성되었습니다^^
네이게이션 기능 되고요~ 셀렉트박스로 로우 갯수 선택 기능 되고요~ No탭 클릭하시면 정렬 기능 됩니다요~

마무리요

실행화면 출력하고 보니 아직도 맛!보!기! 인것을 보면 아직 한참 멀은 듯 합니다.
더 알찬 정보로 준비하도록 하겠습니다^^
감사합니다. 


참고자료 :
http://haacked.com/archive/2009/04/14/using-jquery-grid-with-asp.net-mvc.aspx
http://www.trirand.com/jqgridwiki/doku.php?id=wiki:pager&s[]=paging&s[]=properties

안녕하세요. Visual C# MVP 남정현입니다.

정규 강좌를 올리기 전에, 몇 가지 Windows Azure에 관련된 국내외 소식을 종합하는 업데이트 아티클들을 올려봅니다. 이번 업데이트에 반영된 내용들은 Windows Azure를 개발 플랫폼으로 택하시는 데에 있어서 중요한 정보들을 많이 포함하고 있습니다.

1. Windows Azure Tools for Visual Studio 1.2, Windows Azure SDK 1.2, Windows Azure Platform Training Kit 2010.06 업데이트 및 Windows Azure Tools 한글화!

Windows Azure Tools for Visual Studio, Windows Azure SDK, Windows Azure Platform Training Kit의 새 버전이 출시되었습니다. 이번 버전에서 가장 중점적으로 개선된 것은 Visual Studio 2010과의 연동과 .NET Framework 4.0에 대한 지원이며, 특히 최근에 중국어 간체, 중국어 번체, 일본어, 한국어 등 영어 이외의 다수 언어를 위한 Language Pack까지 같이 업데이트된 것이 주목할만한 점입니다. 아직 정식 Windows Azure 서비스가 출시되지는 않았지만 개발 도구에 대한 준비가 좀 더 완벽해진 것은 반길만한 일입니다. 이에 대한 자세한 내용은 http://www.rkttu.com/410 를 참고해주십시오.

2. Windows Azure AppFabric 2010.07 업데이트 및 SDK 출시

Windows Azure Tools for Visual Studio 1.2와 Windows Azure SDK 1.2 출시와 더불어서 Windows Azure AppFabric의 새 버전이 업데이트되었습니다. 이번 버전에서는 모바일 및 웹 브라우저 기반의 클라이언트 및 Microsoft Silverlight, Adobe Flash 기반의 RIA 클라이언트에서 직접 Service Bus나 Access Control에 접근할 수 있도록 개선된 것이 가장 큰 주안점입니다. 특히 RIA 클라이언트에서 AppFabric Service Bus나 Access Control에 접근하는데에 있어서 가장 큰 장애 요소였던 Cross Domain Policy에 대한 지원이 추가되었습니다. 더불어서 Windows Azure AppFabric SDK의 이번 버전에서는 .NET Framework 4.0에 대한 지원이 추가되었습니다. 좀 더 자세한 내용은 http://www.rkttu.com/414 를 참고하여 주십시오.

3. Codename: Dallas @ WWPC2010 업데이트

Codename: Dallas는 Windows Azure Platform과 더불어서 같이 제공되는 새로운 유형의 데이터 공급자 서비스로 각종 프리미엄 통계 자료, 뉴스, 동향 등의 정보를 ATOM, XML, Open Data Protocol 등의 데이터 형식을 이용하여 손쉽게 가져올 수 있습니다. 현재 확정된 데이터 공급사 (NASA, National Geographic, Associated Press, Zillow.com, Weather Central, NAVTEQ 등)외에도 아래의 그림에서 언급하는 추가 제공사들을 포함하여 올해 4분기에 Codename: Dallas가 정식 서비스로 전환될 예정에 있으며, 8월 중에 새로운 UI를 포함하는 CTP가 런칭될 예정이라고 합니다. 이에 대한 원문 기사는 http://blogs.msdn.com/b/zaneadam/archive/2010/07/12/news-on-microsoft-codename-dallas-at-wwpc-2010.aspx 에서 확인하실 수 있습니다.

4. Windows Azure Platform Appliance 발표

그 동안 Windows Azure Platform 자체는 전형적인 Public Cloud Platform으로서 잘 알려져있었고, 이에 대한 Counter Product로 Hyper-V나 System Center 등의 제품군이 Private Cloud Platform으로 소개되는 일이 많았습니다만 Windows Azure Platform의 기술 자체를 Private Cloud Platform화 하는데에 필요한 새로운 제품을 런칭하였습니다. 좀 더 자세한 정보는 http://www.rkttu.com/412 에서 확인하실 수 있습니다.

다음 강좌부터는 한글화된 Windows Azure Tools for Visual Studio 2010을 기반으로하는 Twitter Style의 Azure Guestbook 만들기 Walkthrough 강좌를 진행할 예정입니다. 많은 관심 부탁드립니다. :-)

I'd like to thank all those who have believed in and supported me. - a digression about Imagine Cup 2010

[수정] 누락된 이미지 파일을 추가하였습니다.