티스토리 뷰
LINQ TO Sql 은 데이터베이스를 엑세스 하고 쿼리하는데 데이터베이스와 어플케이션간에 많은 장벽을 없애버렸다. 바로 어플케이션에서 쉽게 SQL 쿼리를 사용할 수 있기 때문이다.
하지만, 이와 같이 장벽이 사라진 만큼 데이터베이스와 어플케이션의 더욱 더 깊은 이해가 요구 되어야 더욱 더 섬세하고 좋은 성능을 낼 수가 있을 것이다.
일반적인 데이터엑세스 과정
대략 위와 같은 논리적인(또는 물리적인) 3 Layer 형태가 갖추어 질 것이다.(위 그림 정말 못그렸다.;;)
그렇다면 LINQ TO Sql 의 사용은 Data Access Layer 가 가장 적절할 것 같다.
LINQ TO Sql 클래스를 만들어, 비쥬얼하게 멋진 다이어그램과 사용할 프로시져를 끌어다 놓는 것 만으로 SqlParameter 를 만드는 귀찮은 작업은 생략될 수 있을 것이다.
그렇다면 왜 Data Access 에서만 LINQ TO Sql 을 사용해야 할까
이유는 간단하다. 바로 디스어셈블러 때문이다.
데이터베이스의 ConnectionString 은 자동으로 app.config 에 기어 들어간다고 쳐도, 데이터베이스의 테이블 스키마와 관계 등이 그대로 노출 될 수 있다.
다음은 LINQ TO Sql 이 만들어 주는 Entity 클래스의 일부이다.
다음은 LINQ TO Sql 이 만들어 주는 Entity 클래스의 일부이다.
아래는 LINQ 쿼리가 어떻게 디스어셈블리 되는지 보여준다.
var joinList = from c in db.Comments
group c by c.ArticleNo into g_c
join a in db.Articles on g_c.Key equals a.ArticleNo
orderby g_c.Key ascending
select new
{
g_c.Key,
a.Title,
CommentCount = g_c.Count()
}; |
var joinList = db.Comments.GroupBy<Comment, int>(Expression.Lambda<Func<Comment, int>>(Expression.Property(CS$0$0000 = Expression.Parameter(typeof(Comment), "c"), (MethodInfo) methodof(Comment.get_ArticleNo)), new ParameterExpression[] { CS$0$0000 })).Join(db.Articles, Expression.Lambda<Func<IGrouping<int, Comment>, int>>(Expression.Property(CS$0$0000 = Expression.Parameter(typeof(IGrouping<int, Comment>), "g_c"), (MethodInfo) methodof(IGrouping<int, Comment>.get_Key, IGrouping<int, Comment>)), new ParameterExpression[] { CS$0$0000 }), Expression.Lambda<Func<Article, int>>(Expression.Property(CS$0$0000 = Expression.Parameter(typeof(Article), "a"), (MethodInfo) methodof(Article.get_ArticleNo)), new ParameterExpression[] { CS$0$0000 }), Expression.Lambda(Expression.New((ConstructorInfo) methodof(<>f__AnonymousType0<IGrouping<int, Comment>, Article>..ctor, <>f__AnonymousType0<IGrouping<int, Comment>, Article>), new Expression[] { CS$0$0000 = Expression.Parameter(typeof(IGrouping<int, Comment>), "g_c"), CS$0$0002 = Expression.Parameter(typeof(Article), "a") }, new MethodInfo[] { (MethodInfo) methodof(<>f__AnonymousType0<IGrouping<int, Comment>, Article>.get_g_c, <>f__AnonymousType0<IGrouping<int, Comment>, Article>), (MethodInfo) methodof(<>f__AnonymousType0<IGrouping<int, Comment>, Article>.get_a, <>f__AnonymousType0<IGrouping<int, Comment>, Article>) }), new ParameterExpression[] { CS$0$0000, CS$0$0002 })).OrderBy(Expression.Lambda(Expression.Property(Expression.Property(CS$0$0000 = Expression.Parameter(typeof(<>f__AnonymousType0<IGrouping<int, Comment>, Article>), "<>h__TransparentIdentifier0"), (MethodInfo) methodof(<>f__AnonymousType0<IGrouping<int, Comment>, Article>.get_g_c, <>f__AnonymousType0<IGrouping<int, Comment>, Article>)), (MethodInfo) methodof(IGrouping<int, Comment>.get_Key, IGrouping<int, Comment>)), new ParameterExpression[] { CS$0$0000 })).Select(Expression.Lambda(Expression.New((ConstructorInfo) methodof(<>f__AnonymousType1<int, string, int>..ctor, <>f__AnonymousType1<int, string, int>), new Expression[] { Expression.Property(Expression.Property(CS$0$0000 = Expression.Parameter(typeof(<>f__AnonymousType0<IGrouping<int, Comment>, Article>), "<>h__TransparentIdentifier0"), (MethodInfo) methodof(<>f__AnonymousType0<IGrouping<int, Comment>, Article>.get_g_c, <>f__AnonymousType0<IGrouping<int, Comment>, Article>)), (MethodInfo) methodof(IGrouping<int, Comment>.get_Key, IGrouping<int, Comment>)), Expression.Property(Expression.Property(CS$0$0000, (MethodInfo) methodof(<>f__AnonymousType0<IGrouping<int, Comment>, Article>.get_a, <>f__AnonymousType0<IGrouping<int, Comment>, Article>)), (MethodInfo) methodof(Article.get_Title)), Expression.Call(null, (MethodInfo) methodof(Enumerable.Count), new Expression[] { Expression.Property(CS$0$0000, (MethodInfo) methodof(<>f__AnonymousType0<IGrouping<int, Comment>, Article>.get_g_c, <>f__AnonymousType0<IGrouping<int, Comment>, Article>)) }) }, new MethodInfo[] { (MethodInfo) methodof(<>f__AnonymousType1<int, string, int>.get_Key, <>f__AnonymousType1<int, string, int>), (MethodInfo) methodof(<>f__AnonymousType1<int, string, int>.get_Title, <>f__AnonymousType1<int, string, int>), (MethodInfo) methodof(<>f__AnonymousType1<int, string, int>.get_CommentCount, <>f__AnonymousType1<int, string, int>) }), new ParameterExpression[] { CS$0$0000 })); |
일일이 탭도 맞추고 정렬한 후에야 비로소 볼만 하겠지만, 조막만한 쿼리가 어쨌든 알아보긴 힘들지만 역어셈블리가 되었다.
그렇다면 충분히 어셈블리의 IL 코드를 조작하여, 원하는 데이터를 리턴시키기엔 충분할 것이다. (쉽지 않겠지만^^;)
위의 무지막지한 디스어셈브리 코드를 보면, LINQ TO Sql 의 성능마저 궁금하게 만든다.
하지만, 성능 테스트는 다음으로 슬쩍 미루도록 해야겠다. (음하하;;)
왜냐하면 난 소중하니까 ^^
'.NET > C#' 카테고리의 다른 글
[C# 3.0] LINQ to Sql 의 쿼리를 로그로 남겨보자 (0) | 2007.12.04 |
---|---|
LINQ QUIZ (0) | 2007.11.05 |
확장 메서드의 설계(Architect) (1) | 2007.09.12 |
람다식(Lambda Expressions) 을 이용한 확장 메서드(Extension Methods) 만들기 [2] (1) | 2007.09.09 |
람다식(Lambda Expressions) 을 이용한 확장 메서드(Extension Methods) 만들기 [1] (1) | 2007.09.08 |
- TAG
- c#, C# 3.0, LINQ, linq to sql
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- 2,841,738
- Today
- 3
- Yesterday
- 47
링크
- ***** MY SOCIAL *****
- [SOCIAL] 페이스북
- [SOCIAL] 팀 블로그 트위터
- .
- ***** MY OPEN SOURCE *****
- [GITHUB] POWERUMC
- .
- ***** MY PUBLISH *****
- [MSDN] e-Book 백서
- .
- ***** MY TOOLS *****
- [VSX] VSGesture for VS2005,200…
- [VSX] VSGesture for VS2010,201…
- [VSX] Comment Helper for VS200…
- [VSX] VSExplorer for VS2005,20…
- [VSX] VSCmd for VS2005,2008
- .
- ***** MY FAVORITES *****
- MSDN 포럼
- MSDN 라이브러리
- Mono Project
- STEN
- 일본 ATMARKIT
- C++ 빌더 포럼
- .
TAG
- Team Foundation Server
- 땡초
- test
- umc
- github
- Visual Studio
- LINQ
- monodevelop
- Visual Studio 2008
- 비주얼 스튜디오
- Team Foundation Server 2010
- 엄준일
- Managed Extensibility Framework
- Windows 8
- ALM
- POWERUMC
- MEF
- .NET
- testing
- .NET Framework 4.0
- Silverlight
- TFS 2010
- Visual Studio 2010
- TFS
- ASP.NET
- 팀 파운데이션 서버
- c#
- 비주얼 스튜디오 2010
- mono
- Visual Studio 11
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 |
글 보관함
- 2020/05 (1)
- 2019/10 (3)
- 2018/11 (1)
- 2018/08 (2)
- 2017/04 (1)
- 2017/01 (2)
- 2016/11 (2)
- 2016/08 (1)
- 2016/05 (1)
- 2016/04 (2)
- 2016/02 (2)
- 2016/01 (1)
- 2015/05 (1)
- 2015/04 (2)
- 2015/03 (1)
- 2015/02 (1)
- 2015/01 (1)
- 2014/11 (1)
- 2014/09 (2)
- 2014/08 (2)
- 2014/05 (2)
- 2014/04 (3)
- 2014/03 (2)
- 2014/02 (2)
- 2014/01 (4)
- 2013/12 (2)
- 2013/11 (1)
- 2013/10 (2)
- 2013/09 (6)
- 2013/08 (3)