LINQ 는 Language INtegrated Query위 약어로, 컬렉션을 편리하게 다루기 위한 목적으로 만들어진 질의 언어입니다. C# 3.0 버전에서부터 탑재한 LINQ 덕분에 프로그래머들은 데이타를 찾고 병합하고 정렬하는 코드를 작성하는 짐을 상당 부분 내려 놓을 수 있게 되었습니다.
- From : 어떤 데이타 집합에서 찾을 것인가?
- Where : 어떤 값의 데이타를 찾을 것인가? (필터 역할)
- Orderby : 어떤 데이타 순서대로 나열할 것인가?(순서 정하기)
- Select : 어떤 항목을 추출할 것인가?
예제 1 - LINQ 문을 사용하지 않고 프로그램 작성
키가 175 미만인 데이타만을 골라서 새 컬렉션으로 추출하는 프로그램
class Profile { public string Name { get; set; } public int Height { get; set; } } class Program { static void Main(string[] args) { Profile[] arrProfile = { new Profile{Name = "이순신", Height=210}, new Profile{Name = "강감찬", Height=169}, new Profile{Name = "을지문덕", Height=175}, new Profile{Name = "세종대왕", Height=183}, new Profile{Name = "안창호", Height=159}, new Profile{Name = "연개소문", Height=172} }; // 1단계 - 키가 175 미만인 데이타를 추출함 List<profile> profiles = new List<Profile>(); foreach(Profile profile in arrProfile) { if (profile.Height < 175) profiles.Add(profile); } // 2단계 - 키의 오름차순으로 정열함 profiles.Sort( (profile1, profile2) => { return profile1.Height - profile2.Height; } ); // 3단계 - 출력함 foreach(var profile in profiles) Console.WriteLine("{0}, {1}", profile.Name, profile.Height); Console.ReadLine(); } }
예제 2 - LINQ 문을 사용하여 프로그램 작성
키가 175 미만인 데이타만을 골라서 새 컬렉션으로 추출하는 프로그램
class Profile { public string Name { get; set; } public int Height { get; set; } } class Program { static void Main(string[] args) { Profile[] arrProfile = { new Profile{Name = "이순신", Height=210}, new Profile{Name = "강감찬", Height=169}, new Profile{Name = "을지문덕", Height=175}, new Profile{Name = "세종대왕", Height=183}, new Profile{Name = "안창호", Height=159}, new Profile{Name = "연개소문", Height=172} }; // 1단계 - 키가 175 미만인 데이타를 추출함 var profiles = from profile in arrProfile where profile.Height < 175 orderby profile.Height ascending select profile; // 2단계 - 출력함 foreach (var profile in profiles) Console.WriteLine("{0}, {1}", profile.Name, profile.Height); Console.ReadLine(); } }
예제3 - select 문의 분석
select 절은 다음과 같이 사용하면 됩니다.
var profiles = from profile in arrProfile where profile.Height < 175 orderby profile.Height ascending select profile;
위의 예에서 var 형식으로 선언된 profiles 의 실제 형식이 궁금할 겁니다. C# 컴파일러가 var 형식을 LINQ 쿼리식이 반환할 결과 형식에 맞춰 알아서 컴파일 해 주기는 하지만, 실제로 var 가 어떤 형식으로 치환되는지를 알아둘 필요가 있습니다. LINQ 질의 결과는 IEnumerable<T> 로 치환되는데, 이 형식 매개변수 T는 select 문에 의해 결정됩니다.
예를 들어 위 LINQ 쿼리식은 배열로부터 175 미만인 Profile 객체를 골라내는데, 그 결과는 IEnumerable<Profile> 형식이 됩니다. 다음과 같이 select 문에서 Profile 객체 전체가 아닌 Name 프로퍼티만 추출하면 profiles는 IEnumerable<string> 형식으로 컴파일됩니다.
var profiles = from profile in arrProfile where profile.Height < 175 orderby profile.Height ascending select profile.Name;
추가적으로 select 문은 무명 형식(Anonymous type)을 이용해서 다음과 같이 새로운 형식을 만들어 낼 수도 있습니다.
var profiles = from profile in arrProfile where profile.Height < 175 orderby profile.Height ascending select new { Name = profile.Name, InchHeight = profile.Height * 0.393 };
전체 소스
class Profile { public string Name { get; set; } public int Height { get; set; } } class Program { static void Main(string[] args) { Profile[] arrProfile = { new Profile{Name = "이순신", Height=210}, new Profile{Name = "강감찬", Height=169}, new Profile{Name = "을지문덕", Height=175}, new Profile{Name = "세종대왕", Height=183}, new Profile{Name = "안창호", Height=159}, new Profile{Name = "연개소문", Height=172} }; // 1단계 - 키가 175 미만인 데이타를 추출함 var profiles = from profile in arrProfile where profile.Height < 175 orderby profile.Height ascending select new { Name = profile.Name, InchHeight = profile.Height * 0.393 }; // 2단계 - 출력함 foreach (var profile in profiles) Console.WriteLine("{0}, {1}", profile.Name, profile.InchHeight); Console.ReadLine(); } }
LINQ 쿼리식은 데이타 원본에 접근하기 위해 from 절을 사용합니다. 여러개의 데이타 원본에 접근하려면 from 절을 중첩해서 사용하면 됩니다.
foreach 문을 중첩해서 사용하는 것처럼 말입니다.
다음의 클래스는 각 학년별, 학급별, 점수를 나타내며, 과목별 점수를 담기 위해 Score 필드를 배열로 선언했습니다.
class GradeClassScore { public int Grade { get; set; } public string ClassName { get; set; } public int[] Score { get; set; } }
그리고 이 클래스를 바탕으로 배열 하나를 다음과 같이 선언했습니다.
GradeClassScore[] arrClass = { new GradeClassScore(){Grade = 1, ClassName = "연두반", Score = new int[]{10, 20, 30, 40, 50}}, new GradeClassScore(){Grade = 1, ClassName = "분홍반", Score = new int[]{65, 75, 85, 95, 100}}, new GradeClassScore(){Grade = 1, ClassName = "파랑반", Score = new int[]{68, 28, 38, 48, 58}}, new GradeClassScore(){Grade = 1, ClassName = "노랑반", Score = new int[]{83, 84, 85, 86, 86}}, new GradeClassScore(){Grade = 1, ClassName = "보라반", Score = new int[]{87, 87, 87, 87, 87}}, new GradeClassScore(){Grade = 2, ClassName = "연두반", Score = new int[]{10, 20, 30, 40, 50}}, new GradeClassScore(){Grade = 2, ClassName = "분홍반", Score = new int[]{65, 75, 85, 95, 100}}, new GradeClassScore(){Grade = 2, ClassName = "파랑반", Score = new int[]{68, 28, 38, 48, 58}}, new GradeClassScore(){Grade = 2, ClassName = "노랑반", Score = new int[]{83, 84, 85, 86, 86}}, new GradeClassScore(){Grade = 2, ClassName = "보라반", Score = new int[]{87, 87, 87, 87, 87}}, new GradeClassScore(){Grade = 3, ClassName = "연두반", Score = new int[]{10, 20, 30, 40, 50}}, new GradeClassScore(){Grade = 3, ClassName = "분홍반", Score = new int[]{65, 75, 85, 95, 100}}, new GradeClassScore(){Grade = 3, ClassName = "파랑반", Score = new int[]{68, 28, 38, 48, 58}}, new GradeClassScore(){Grade = 3, ClassName = "노랑반", Score = new int[]{83, 84, 85, 86, 86}}, new GradeClassScore(){Grade = 3, ClassName = "보라반", Score = new int[]{87, 87, 87, 87, 87}} };
이제 준비는 마쳤습니다. 위 배열에서 1학년 중에서 점수가 60점 미만인 학급과 과목 점수를 중첩 from 절을 이용해서 뽑아 보겠습니다. 그리고 여기서 한가지 팁을 더 알려 드리자면 where 절에 and, or 를 포함 시킬 수 있습니다. 즉 and => &&, or => || 를 사용하시면 됩니다.
var classes = from c in arrClass from s in c.Score where s < 60 && c.Grade == 1 orderby s select new { c.ClassName, Lowest = s };
전체 소스
class GradeClassScore { public int Grade { get; set; } public string ClassName { get; set; } public int[] Score { get; set; } } class Program { static void Main(string[] args) { GradeClassScore[] arrClass = { new GradeClassScore(){Grade = 1, ClassName = "연두반", Score = new int[]{10, 20, 30, 40, 50}}, new GradeClassScore(){Grade = 1, ClassName = "분홍반", Score = new int[]{65, 75, 85, 95, 100}}, new GradeClassScore(){Grade = 1, ClassName = "파랑반", Score = new int[]{68, 28, 38, 48, 58}}, new GradeClassScore(){Grade = 1, ClassName = "노랑반", Score = new int[]{83, 84, 85, 86, 86}}, new GradeClassScore(){Grade = 1, ClassName = "보라반", Score = new int[]{87, 87, 87, 87, 87}}, new GradeClassScore(){Grade = 2, ClassName = "연두반", Score = new int[]{10, 20, 30, 40, 50}}, new GradeClassScore(){Grade = 2, ClassName = "분홍반", Score = new int[]{65, 75, 85, 95, 100}}, new GradeClassScore(){Grade = 2, ClassName = "파랑반", Score = new int[]{68, 28, 38, 48, 58}}, new GradeClassScore(){Grade = 2, ClassName = "노랑반", Score = new int[]{83, 84, 85, 86, 86}}, new GradeClassScore(){Grade = 2, ClassName = "보라반", Score = new int[]{87, 87, 87, 87, 87}}, new GradeClassScore(){Grade = 3, ClassName = "연두반", Score = new int[]{10, 20, 30, 40, 50}}, new GradeClassScore(){Grade = 3, ClassName = "분홍반", Score = new int[]{65, 75, 85, 95, 100}}, new GradeClassScore(){Grade = 3, ClassName = "파랑반", Score = new int[]{68, 28, 38, 48, 58}}, new GradeClassScore(){Grade = 3, ClassName = "노랑반", Score = new int[]{83, 84, 85, 86, 86}}, new GradeClassScore(){Grade = 3, ClassName = "보라반", Score = new int[]{87, 87, 87, 87, 87}} }; var classes = from c in arrClass from s in c.Score where s < 60 && c.Grade == 1 orderby s select new { c.ClassName, Lowest = s }; foreach(var c in classes) Console.WriteLine("낙제 : {0} ({1})", c.ClassName, c.Lowest); Console.ReadLine(); } }
'C# with LINQ to SQL' 카테고리의 다른 글
LINQ - 4칙 연산(select, insert, update, delete) - DataGridView 이용 (0) | 2015.07.01 |
---|---|
LINQ - 로그인창 적용 (0) | 2015.06.25 |
LINQ - 조인(내부조인, 그룹조인, 왼쪽 우선 외부 조인) (0) | 2015.06.22 |
LINQ - 그룹핑2 (0) | 2015.06.19 |
LINQ - 그룹핑1 (0) | 2015.06.18 |