================================ Outline ====================================
LINQ
- groupby
- 기초문법
- join
- 표준연산자
- LINQ를 사용한 성적처리 프로그램
----------------------------------------------------------------------------
LINQ
[Group by를 활용한 데이터 분류]
group by는 특정기준으로 데이터를 분류하는 기능을 수행한다.
키워드는 group * by * into 이다
ex) var listprofile = from profile in arrProfile
group profile by profile.Height < 175 into g
select new { GroupKey = g.Key, Profiles = g};
LINQ의 기본 문법이 부족함으로 보충을 해보자.
LINQ의 기본 키워드는 from, where, oderby, select로 나눈다. 각 키워드의 문법과 세부내용을 학습해보자
[LINQ 기초 문법]
from
from은 쿼리식의 대상이 되는 데이터 원본과 각 요소 데이터를 나타내는 범위 변수를 지정해 주어야 한다.
이 때 범위 변수는 foreach문에서의 반복 변수와 비슷한데 이 둘의 차이점은 반복 변수는 데이터의 원본으로부터 데이터를 가져와 담아내지만, 범위 변수는 실제로 담아내지 않는다.

범위 변수는 데이터 원본이 결정되면 자동적으로 결정됨으로 특별히 신경쓰지 않아도 된다.
문법은, from * in * 이다.
ex) var result = from n in numbers
where
where는 필터 역할을 하는 연산자입니다.
교재 p/449 GroupBy 예제,
using System; using System.Linq;
namespace _20150618 { 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 = 186}, new Profile(){Name="김태희", Height = 158}, new Profile(){Name="고현정", Height = 172}, new Profile(){Name="이문세", Height = 178}, new Profile(){Name="하하", Height = 171} };
var listProfile = from profile in arrProfile orderby profile.Height group profile by profile.Height < 175 into g select new { GroupKey = g.Key, Profiles = g };
foreach (var Group in listProfile) { Console.WriteLine("-175cm 미만? : {0}", Group.GroupKey);
foreach (var profile in Group.Profiles) { Console.WriteLine(" {0}, {1}", profile.Name, profile.Height); } } } } } |

//groupby는 분류된 자료를 따로 출력해주는 것이 아니라 분류하여 출력하는 기능을 한다.
예제의 코드를 분석해 보자.
var listProfile = from profile in arrProfile
orderby profile.Height
group profile by profile.Height < 175 into g
select new { GroupKey = g.Key, Profiles = g };
Join
join은 두 데이터 원본을 연결하는 연산이다.
조인에는 내부 조인과 외부조인이 있다.
내부 조인은 두 데이터 원본 사이에서 일치하는 데이터만 연결한 후 반환하는 것이다. 이것은 교집합의 개념과 같다.
문법은 다음과 같다.
from a in A
join b in B on a.XXXX equals b.YYYY
var listProfile =
from profile in arrProfile
join product in arrProduct on profile.Name equal productStar
select new
{
Name = profile.Name,
Work = product.Title,
Height = profile.Height
};
외부 조인은 조인 결과에 기준 되는 데이터 원본은 모두 포함된다는 점을 제외하고는 내부 조인과 같다.
문법은 다음과 같다.
var listProfile =
from profile in arrProfile
join product in arrProduct on profile.Name equals product.Star into ps
from product in ps.DefaultIfEmpty(new Product(){Title="그런거 없음"})
select new
{
Name = profile.Name,
Work = product.Title,
Height = profile.Height
};
교재 p/454 조인 예제,
using System; using System.Linq;
namespace join { class Profile { public string Name { get; set; } public int Height { get; set; }
} class Product { public string Title { get; set; } public string Star { get; set; }
} class Program { static void Main(string[] args) { Profile[] arrProfile = { 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[] arrProduct = { new Product(){Title="비트", Star ="정우성"}, new Product(){Title="CF 다수", Star ="김태희"}, new Product(){Title="아이리스", Star ="김태희"}, new Product(){Title="모래시계", Star ="고현정"}, new Product(){Title="Solo 예찬", Star ="이문세"}, };
var listProfile = from profile in arrProfile join product in arrProduct on profile.Name equals product.Star select new { Name = profile.Name, Work = product.Title, Height = profile.Height };
Console.WriteLine("--- 내부 조인 결과 ---"); foreach (var profile in listProfile) { Console.WriteLine("이름:{0}, 작품:{1}, 키:{2}cm", profile.Name, profile.Work, profile.Height); }
listProfile = from profile in arrProfile join product in arrProduct on profile.Name equals product.Star into ps from product in ps.DefaultIfEmpty(new Product() {Title = "그런거 없음"}) select new { Name = profile.Name, Work = product.Title, Height = profile.Height };
Console.WriteLine(); Console.WriteLine("--- 외부 조인 결과 ---"); foreach (var profile in listProfile) { Console.WriteLine("이름:{0}, 작품:{1}, 키:{2}cm", profile.Name, profile.Work, profile.Height); } } } }
|

[LINQ의 표준 연산자]
//Quary문은 한 번 설정되면 수정 및 재작성이 잦지 않음으로 개발자들 입장에서는 익숙해지기 어려운 구문이다.
교재 p/464 LINQ의 표준 연산자 예제,
using System; using System.Linq;
namespace MinMaxAvg { 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 = 186}, new Profile(){Name = "김태희", Height = 158}, new Profile(){Name = "고현정", Height = 172}, new Profile(){Name = "이문세", Height = 178}, new Profile(){Name = "하하", Height = 171}
};
var heightStat = from profile in arrProfile group profile by profile.Height < 175 into g select new { Group = g.Key == true? "175미만":"175이상", Count = g.Count(), Max = g.Max(profile => profile.Height), Min = g.Min(profile => profile.Height), Average = g.Average(profile => profile.Height) }; foreach (var stat in heightStat) { Console.Write("{0} - Count : {1}, Max : {2}, ", stat.Group, stat.Count, stat.Max); Console.WriteLine("Min : {0}, Average : {1}", stat.Min, stat.Average); }
} } }
|

LINQ를 활용한 성적처리 프로그램
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Collections;
namespace ConsoleApplication5 { class Student { string name;
public string Name { get { return name; } set { name = value; } } int math;
public int Math { get { return math; } set { if (value < 0 && value > 100) { math = 0; } math = value; } } int science;
public int Science { get { return science; } set { if (value < 0 && value > 100) { science = 0; } science = value; } } int english;
public int English { get { return english; } set { if (value < 0 && value > 100) { english = 0; } english = value; } } int avg;
public int Avg { get { return avg; } set { avg = value; } } public void Show() { Console.Write("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t", Name, Math, English, Science, (english + math + science), (english + math + science) / 3); } } class Program { static void Main(string[] args) { string name; Student std; ArrayList arr = new ArrayList(); while (true) { Console.Write("이름을입력하세요..하기싫으면 q : "); name = Console.ReadLine(); if (name == "q") { break; } std = new Student(); std.Name = name; Console.Write("수학점수 : "); std.Math = int.Parse(Console.ReadLine()); Console.Write("영어점수 : "); std.English = int.Parse(Console.ReadLine()); Console.Write("과학점수 : "); std.Science = int.Parse(Console.ReadLine()); std.Avg = (std.Math + std.English + std.Science) / 3; arr.Add(std); Console.WriteLine("입력이완료되었음!!"); } Console.WriteLine("출력"); Console.WriteLine(" 이름 수학 영어 과학 총점 평균 순위"); var query = from Student student in arr orderby student.Avg descending select student; int c = 1; foreach (Student s in query) { s.Show(); Console.WriteLine(c); c++; } Console.ReadLine();
var list1 = from Gst in query group Gst by Gst.Math > 0 into N select new { Count = N.Count(), Max = N.Max(Gst => Gst.Math), Min = N.Min(Gst => Gst.Math), Average = N.Average(Gst => Gst.Math) };
foreach(var print in list1) { Console.WriteLine("Math :: Highest : {0} | Lowest : {1} | Average : {2}", print.Max, print.Min, print.Average); }
var list2 = from Gst in query group Gst by Gst.English > 0 into N select new { Count = N.Count(), Max = N.Max(Gst => Gst.English), Min = N.Min(Gst => Gst.English), Average = N.Average(Gst => Gst.English) };
foreach(var print in list2) { Console.WriteLine("English :: Highest : {0} | Lowest : {1} | Average : {2}", print.Max, print.Min, print.Average); }
var list3 = from Gst in query group Gst by Gst.Science > 0 into N select new { Count = N.Count(), Max = N.Max(Gst => Gst.Science), Min = N.Min(Gst => Gst.Science), Average = N.Average(Gst => Gst.Science) };
foreach (var print in list3) { Console.WriteLine("Science :: Highest : {0} | Lowest : {1} | Average : {2}", print.Max, print.Min, print.Average);
}
} } } |
