programing

LINQ는 내부적으로 어떻게 작동합니까?

copyandpastes 2021. 1. 14. 23:37
반응형

LINQ는 내부적으로 어떻게 작동합니까?


.net에서 LINQ를 사용하는 것을 좋아하지만 내부적으로 어떻게 작동하는지 궁금합니다.

아는 사람 있나요?

Thks.


LINQ의 특정 측면에 대해 묻는 것이 더 합리적입니다. 그렇지 않으면 "Windows 작동 방식"을 묻는 것과 비슷합니다.

LINQ의 핵심 부분은 C # 관점에서 볼 때 다음과 같습니다.

  • 식 트리. 이는 코드를 데이터로 표현한 것입니다. 예를 들어, 표현식 트리는 "문자열 매개 변수를 가져 와서 Length 속성을 호출 한 다음 결과를 반환합니다"라는 개념을 나타낼 수 있습니다. 이것이 컴파일 된 코드 가 아니라 데이터로 존재한다는 사실은 LINQ to SQL과 같은 LINQ 공급자가이를 분석하고 SQL로 변환 할 수 있음을 의미합니다.
  • 람다 식. 다음과 같은 표현입니다.

    x => x * 2
    (int x, int y) => x * y
    () => { Console.WriteLine("Block"); Console.WriteLine("Lambda"); }
    

    Lambda 식은 대리자 또는 식 트리 로 변환됩니다 .

  • 익명 유형. 다음과 같은 표현입니다.

    new { X=10, Y=20 }
    

    이들은 여전히 ​​정적으로 형식화되어 있으며 컴파일러가 속성 XY. 이들은 일반적으로 var초기화 표현식에서 지역 변수의 유형을 유추 할 수 있도록 사용됩니다.

  • 쿼리 식. 다음과 같은 표현입니다.

    from person in people
    where person.Age < 18
    select person.Name
    

    이들은 C # 컴파일러에 의해 "일반"C # 3.0 (즉, 쿼리 표현식을 사용하지 않는 양식)으로 변환됩니다. 나중에 오버로드 해결 등이 적용되는데, 이는 컴파일러가 Queryable과 같은 유형에 대한 지식이 없어도 여러 데이터 유형에 동일한 쿼리 구문을 사용할 수있는 데 절대적으로 중요합니다. 위의 표현은 다음과 같이 번역됩니다.

    people.Where(person => person.Age < 18)
          .Select(person => person.Name)
    
  • 확장 방법. 이들은 첫 번째 매개 변수 유형의 인스턴스 메소드 인 것처럼 사용할 수있는 정적 메소드입니다. 예를 들어, 다음과 같은 확장 방법 :

    public static int CountAsciiDigits(this string text)
    {
        return text.Count(letter => letter >= '0' && letter <= '9');
    }
    

    그런 다음 다음과 같이 사용할 수 있습니다.

    string foo = "123abc456";
    int count = foo.CountAsciiDigits();
    

    의 구현 CountAsciiDigits에서는 다른 확장 메서드 인 Enumerable.Count().

이것이 대부분의 관련 언어 측면입니다. 그런 다음 LINQ to Objects 및 LINQ to SQL 등과 같은 LINQ 공급자에 표준 쿼리 연산자의 구현이 있습니다. LINQ to Objects를 구현하는 것이 합리적으로 간단한 방법에 대한 프레젠테이션 이 있습니다. C # "Talks" 페이지에 있습니다. in Depth 웹 사이트.

LINQ to SQL과 같은 공급자가 작동하는 방식은 일반적으로 Queryable클래스 를 통해 이루어 집니다. 핵심에서 식 트리를 다른 쿼리 형식으로 변환 한 다음 이러한 out-of-process 쿼리를 실행 한 결과로 적절한 개체를 구성합니다.

관심있는 모든 내용이 포함됩니까? 특별히 알고 싶은 사항이있는 경우 질문을 수정하시면됩니다.


LINQ는 기본적으로 다음과 같은 C # 3.0 개별 기능의 조합입니다.

  • 지역 변수 유형 추론
  • 자동 속성 (VB 9.0에서 구현되지 않음)
  • 확장 방법
  • 람다 식
  • 익명 유형 이니셜 라이저
  • 쿼리 이해

여기까지가는 여정 (LINQ)에 대한 자세한 내용은 LANGNET 2008의 Anders 동영상을 참조하세요.

http://download.microsoft.com/download/c/e/5/ce5434ca-4f54-42b1-81ea-7f5a72f3b1dd/1-01%20-%20CSharp3%20-%20Anders%20Hejlsberg.wmv


간단한 양식에서 컴파일러는 코드 쿼리를 가져 와서 일련의 일반 클래스 및 호출로 변환합니다. 아래에서 Linq2Sql의 경우 DbCommand, DbDataReader 등을 사용하여 동적 SQL 쿼리가 생성되고 실행됩니다.

당신이 가지고 있다고 :

var q = from x in dc.mytable select x;

다음 코드로 변환됩니다.

IQueryable<tbl_dir_office> q = 
    dc.mytable.Select<tbl_dir_office, tbl_dir_office>(
        Expression.Lambda<Func<mytable, mytable>>(
            exp = Expression.Parameter(typeof(mytable), "x"), 
            new ParameterExpression[] { exp }
        )
    );

많은 제네릭, 엄청난 오버 헤드.


Basically linq is a mixture of some language facilities (compiler) and some framework extensions. So when you write linq queries, they get executed using appropriate interfaces such as IQuerable. Also note that the runtime has no role in linq.

But it is difficult to do justice to linq in a short answer. I recommend you read some book to get yourself in it. I am not sure about the book that tells you internals of Linq but Linq in Action gives a good handson about it.


I have a small C# program which demonstrates the implementation of LINQ in C#.

class Program
{
    static void Main(string[] args)
    {
        //Eventhough we call the method here, it gets called ONLY when the for loop is executed
        var Cities = LinQFunction(new List<string>() { "Bangalore", "Mysore", "Coorg", "Tumkur", "Kerala", "TamilNadu" });

        //LinQFunction() gets callled now
        foreach(var city in Cities)
        {
            Console.WriteLine(city);
        }
    }

   //This function is called ONLY when the foreach loop iterates and gets the item from the collection
   static IEnumerable<string> LinQFunction(List<string> cities)
    {
        foreach (var item in cities)
        {
            //Return each 'item' at a time 
            yield return item;
        }
    }
}

Use appropriate breakpoints.

ReferenceURL : https://stackoverflow.com/questions/671235/how-linq-works-internally

반응형