... | ... | @@ -208,9 +208,107 @@ Array.ForEach(enumList.ToArray(), (elem) => { Console.WriteLine(elem); }); |
|
|
|
|
|
|
|
|
|
|
|
# 6. 아래 코드를 분석해주세요.
|
|
|
|
|
|
|
|
|
***
|
|
|
***
|
|
|
___Delegate 체인___
|
|
|
|
|
|
#### Expression Trees (ETs)
|
|
|
|
|
|
Expression 객체의 인스턴스 데이터의 역할을 하는 람다 식
|
|
|
Expression 객체는 데이터를 트리 자료구조 형태로 담고 있다. (Expression Tree)
|
|
|
Expression.Compile : 데이터로 담겨 있는 람다 식은 컴파일이 가능함, 이 함수는 델리게이트를 반환하고 따라서 함수 호출이 가능함.
|
|
|
|
|
|
람다 식을 직접 구성하여 Expression 트리를 구성할 수 있음.
|
|
|
여러가지 메서드를 제공함 (Expression 타입의 팩터리 메서드, System.Linq.Expressions에 정의)
|
|
|
궁극적으로 Expression의 여러 팩토리 메서드를 이용해서 C#코드를 프로그램 실행 시점에 만들어 내는것이 가능 함.
|
|
|
|
|
|
개발 보다는, 지원 툴, 컴파일러 관련 부분 개발시 유용한 기능
|
|
|
|
|
|
참고 : ExpressionTreeVisualizer (http://msdn.microsoft.com/ko-kr/library/bb397975(v=vs.90).aspx)
|
|
|
1. Body : expression의 몸체를 리턴한다.
|
|
|
2. Parameters : 람다식의 파라미터를 리턴한다.
|
|
|
3. NodeType : Expression trees의 특정노드의 ExpressionType을 리턴한다. ExpressionType은
|
|
|
45가지의 값을 가진 열거형타입인데, Expression trees에 속할 수 있는 모든 노드의 목록이 포함되어
|
|
|
있다. 예를 들면, 상수를 리턴하거나, 파라미터를 리턴한다거나, 둘 중에 뭐가 더 큰지 결정한다거나
|
|
|
(<,>), 두 값을 더한다거나(+) 하는 것들이 있다.
|
|
|
4. Type : expression의 정적인 타입을 리턴한다. 위의 예제 같은 경우에는 Func<int, int, int>이다.
|
|
|
|
|
|
#### LINQ (Language INtegrated Query)
|
|
|
|
|
|
C# 목표중에서 하나는 데이터베이스의 접속 및 제어 방식이 언어 자체에 잘 녹아들도록 만드는 것, MS는 사용자가 직접적인 데이터엑세스
|
|
|
서비스를 추가하지 않아도 C#의 구문 자체에서 데이터를 제어하길 원함. LINQ(Language Integrated Query)의 탄생
|
|
|
|
|
|
언어에 통합된 쿼리표현식(Query Expressions)
|
|
|
함수형 언어 개념을 도입하여 쿼리 형태의 표현식을 제공하여 데이터 추출과 연산에 추상화 단계 굉장히 높힌 표현식.
|
|
|
|
|
|
LINQ를 통해 데이터를 가져오는 방법
|
|
|
1) Select, First 같은 메서드에 람다식을 조합해서 사용
|
|
|
2) 쿼리 구문을 통해서 가져오는 방법 (쿼리 표현식은 데이터를 어떻게 가져오는지 좀 더 명확하고 구체적으로 설명해주는 장점이 있음, SQL 쿼리와 흡사)
|
|
|
|
|
|
|
|
|
LINQ의 종류
|
|
|
|
|
|
LINQ to Object
|
|
|
LINQ to SQL
|
|
|
LINQ to ADO.NET Data Entities
|
|
|
LINQ to Data Set
|
|
|
LINQ to XML
|
|
|
...
|
|
|
|
|
|
Expression tree와 LINQ의 관계
|
|
|
LINQ to SQL의 경우 쿼리 표현식으로 데이터를 얻을 경우
|
|
|
반환 타입이 IQueryable이다.
|
|
|
|
|
|
IQueryable의 정의
|
|
|
public interface IQueryable : IEnumerable
|
|
|
{
|
|
|
Type ElementType { get; }
|
|
|
Expression Expression { get; }
|
|
|
IQueryProvider Provider { get; }
|
|
|
}
|
|
|
|
|
|
|
|
|
멤버로 Expression타입의 프로퍼티를 가지고 있다.
|
|
|
IQueryable의 인스턴스는 expression tree를 가지고 있도록 설계됨.
|
|
|
그 expression tree가 코드로 작성한 LINQ 쿼리문의 자료구조다.
|
|
|
|
|
|
SQL 쿼리는 실제로 데이터베이스 서버에서 실행되기 때문에, 데이터베이스가 알아들을 수 있는 형태로 변환을 해야한다.
|
|
|
예를 들면,
|
|
|
|
|
|
```
|
|
|
SELECT [t0].[uId], [t0].[nickname]
|
|
|
FROM [dbo].[Users] AS [t0]
|
|
|
WHERE [t0].[nickname] = @p0
|
|
|
```
|
|
|
|
|
|
이렇게 문자열 형태로 만들어서 다른 프로세스에 사용되게끔 보내게 되는데,
|
|
|
IL 코드를 SQL 쿼리로 변환하는 것보다, Expression tree 같은 자료구조 형태가 변환하기도 쉽고, 최적화 같은 중간과정 처리도 용이하다고 함.
|
|
|
|
|
|
LINQ to Objects를 통해서 쿼리를 해보면 결과의 타입은 IEnumerable<T>다.
|
|
|
왜 얘네들은 IQueryable<T>가 아닐까?
|
|
|
|
|
|
IEnumerable<T>의 정의
|
|
|
```
|
|
|
public interface IEnumerable<T> : IEnumerable
|
|
|
{
|
|
|
IEnumerator<T> GetEnumerator();
|
|
|
}
|
|
|
```
|
|
|
|
|
|
즉, Expression타입의 프로퍼티가 없다.
|
|
|
|
|
|
왜냐면, LINQ eo Objects는 같은 프로세스내에서 처리될 객체들을 대상으로 쿼리를 하기 때문에 다른 형태로 변환될 필요가 없기 때문이다.
|
|
|
|
|
|
그렇다면, 굳이 expression tree같은 자료구조로 변환할 필요가 없으니 대략 아래와 같은 규칙이 성립한다.
|
|
|
|
|
|
?코드가 같은 프로그램(또는 프로세스)내에서 실행되는 경우라면 IEnumerable<T>
|
|
|
?쿼리 표현식을 다른 프로그램(또는 프로세스)에서 처리하기 위해서 문자열 형태로 변환해야 한다면 expression tree를 포함하는 IQueryable<T>를 사용
|
|
|
|
|
|
|
|
|
#### LINQ
|
|
|
http://blog.eairship.kr/262
|
|
|
|
|
|
#### Delegate 체인
|
|
|
http://www.csharpstudy.com/DevNote/Article/15 |
|
|
\ No newline at end of file |