LINQ (Language INtergrated Query)

 C#언어에 통합된 데이터 질의기능이 있습니다. 데이터베이스에서 날리는 쿼리 정도 생각하시면 되겠습니다.

53개의 표준 LINQ 연산 메소드 중에서 쿼리식을 지원하는 것은 11가지 입니다. 쿼리식은 표준 LINQ 연산 메소드를 호출하는 원리로 이루어져 있기때문에, 쿼리식이 부족하다 싶을때는 함수호출을 이용하는 것도 하나의 방법입니다. 

여기에서는 몇가지 쿼리들만 정리하겠습니다.  자세한 내용은 MSDN을 참고하세요 

 

가장 기본이 되는 쿼리입니다.

 from 

 쿼리식의 대상이 될 데이터 원본과 안에 들어있는 각 요소 데이터를 나타내는 범위 변수를 지정해주어야 합니다.

 from의 데이터 원본은 IEnumerable<T> 인터페이스를 상속하는 형식이어야 합니다. 

 where

 해당 조건에 부합하는 데이터만을 걸러낼때 사용하는 연산자 입니다.  

 orderby

 데이터의 정렬을 수행하는 연산자입니다.

 select

 최종 결과를 추출합니다.

 

 

다음과 같이 쿼리식을 작성하는 것은 LINQ 표준 메소드를 호출하는 것과 같습니다. 

 LINQ 쿼리식 

 LINQ 메소드 호출방식 

 var profileList = from profile in Profiles

where profile.Height < 175

orderby profile.Height

select

new

{

        Name = Profile.Name,

  InchHeight = profile.Height*0.393

};

  var profileList = Profiles.

Where ( profile=> profile.Height < 175).

Orderby ( profile => profile.Height).

Select ( profile =>

 new

{

        Name = Profile.Name,

        InchHeight = profile.Height*0.393

});

 

 

LINQ 예제를 보겠습니다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CsharpStudy
{
    class Program
    {
        class Profile
        {
            public string name { get; set; }
            public int height { get; set; }
        }

        static void Main(string[] args)
        {
            Profile[] profiles = new Profile[5]
           {
               new Profile(){ name="정우성", height=186 },
               new Profile(){ name="김태희", height=158 },
               new Profile(){ name="고현정", height=172 },
               new Profile(){ name="이문세", height=178 },
               new Profile(){ name="하동훈", height=171 }
           };

            var pro = from profile in profiles           // profiles 원본에서 각 요소 profile 객체에서 
                      where profile.height < 175         // profile.height 값이 175 이하인 데이터를
                      orderby profile.height descending // descending 으로 정렬한다.
                      select profile;                          // 정렬 결과의 profile 객체의 list를 추출한다.

            foreach(var profile in pro)
            {
                Console.WriteLine("{0} , {1}", profile.name, profile.height);
            }  
        }
    }
}

 

 

 

데이터 분류하기

 다음 쿼리식을 통해 데이터를 분류할 수 있습니다.

group A by B into C

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CsharpStudy { class Program { class Profile { public string Name { get; set; } public int[] Score { get; set; } } static void Main(string[] args) { Profile[] profiles = new Profile[5] { new Profile(){ Name="김철수", Score=new int[]{77,39,55} }, new Profile(){ Name="김영희", Score=new int[]{89,80,40} }, new Profile(){ Name="이상훈", Score=new int[]{82,60,82} }, new Profile(){ Name="이세상", Score=new int[]{95,88,91} }, new Profile(){ Name="박철민", Score=new int[]{65,59,72} } }; var grouping = from profile in profiles group profile by profile.Score[0] < 70 into gr select new { Groupkey = gr.Key, Profile = gr }; foreach (var Group in grouping) { if(Group.Groupkey) // by에 의해 분류된 것은 Key값이 True를 갖는다. { Console.WriteLine("원하는 데이터"); } else { Console.WriteLine("나머지 데이터"); } foreach (var profile in Group.Profile) { Console.WriteLine("{0}", profile.Score[0]); } } } } }

 

 

 

select는 객체 자체를 추출해도 되고, 객체의 요소를 추출해도 되며, 위와 같이 무명형식을 만들어 무명형식 객체를 추출할 수도 있습니다.

 

 

 

데이터 연결하기

조인을 통해 두 데이터 원본을 연결할 수 있습니다.

 

내부조인(Inner Join)

두 데이터 원본이 일치하는 데이터만 연결하여 추출합니다.

from a in A

join b in B on a.XX equals by b.YY

join 절의 on 키워드는 조인 조건을 수반합니다. 이때 조인 조건은 동등(Equality)만 허용됩니다.

equals라는 키워드 없이 동등연산자인 == 를 사용해도 됩니다.

 

외부조인(Outer Join)

내부조인은 두 데이터 원본이 일치하는 데이터만 연결하여 추출합니다. 일치하는 데이터가 있을 경우에만 추출하는 반면에

외부조인은 일치하는 데이터가 없으면 빈값을 채워 모두 연결하여 추출합니다.

방법은 내부조인을 진행한 후에 into 키워드를 통해 임시컬렉션에 저장하고, 이 임시 컬렉션에 대해서 DefaultIfEmpty 연산을 수행하여 조인결과에 빈값을 채워 넣습니다.

조인 방식에는 왼쪽조인(Left Join), 오른쪽 조인 (Right Join), 완전 조인(Both Join) 세가지가 있지만,

LINQ는 왼쪽조인만을 지원합니다. 

 

 

조인 예제를 보겠습니다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CsharpStudy
{
    class Program
    {
        class Profile
        {
            public string Name { get; set; }
            public int Height { get; set; }
        }
        
        class Product
        {
            public string Title { get; set; }
            public string Star { get; set; }
        }

        static void Main(string[] args)
        {
            Profile[] Profiles = new Profile[5]
            {
                new Profile() { Name="정우성" , Height=186},
                new Profile() { Name="김태희" , Height=158},
                new Profile() { Name="고현정" , Height=172},
                new Profile() { Name="이문세" , Height=178},
                new Profile() { Name="하하" , Height=171}
            };

            Product[] Products = new Product[6]
            {
                new Product() { Star="정우성" , Title="비트"},
                new Product() { Star="김태희" , Title="CF 다수"},
                new Product() { Star="김태희" , Title="아이리스"},
                new Product() { Star="이문세" , Title="붉은노을"},
                new Product() { Star="고현정" , Title="선덕여왕"},
                new Product() { Star="손예진" , Title="연애시대"}
            };

            var InnerJoinList = from profile in Profiles
                              join product in Products on profile.Name equals product.Star
                              select new
                              {
                                  Name = profile.Name,
                                  Work = product.Title,
                                  Height = profile.Height
                              };

            var OuterJoinList = from profile in Profiles
                                join product in Products on profile.Name equals product.Star into ps
                                from product in ps.DefaultIfEmpty(new Product() { Title = "Null" })
                                select new
                                    {
                                        Name = profile.Name,
                                        Work = product.Title,
                                        Height = profile.Height
                                    };


            Console.WriteLine("===== 내부 조인 결과 ====");
            foreach( var profile in InnerJoinList)
            {
                Console.WriteLine("이름: {0} 작품: {1} 키: {2} ", profile.Name, profile.Work, profile.Height);
            }

            Console.WriteLine(Environment.NewLine+"==== 외부 조인 결과 ====");
            foreach (var profile in OuterJoinList)
            {
                Console.WriteLine("이름: {0} 작품: {1} 키: {2} ", profile.Name, profile.Work, profile.Height);
            }       
        }
    }
}

 

 

 

여기까지, LINQ에 대해 정리해보았습니다.

 

 


 

<참고문헌>

뇌를 자극하는 C# 4.0 프로그래밍 - 박상현 저 

 

 
블로그 이미지

laboputer

소프트웨어를 전공하는 대학생

카테고리

전체보기 (24)
Programming with C# (15)
storage of informati.. (1)
Algorithm (1)
학교수업 (7)