본문 바로가기

C#/Linq

Linq Tutorial

  • Linq란?

LINQ(Language-Integrated Query)는 쿼리 기능을 C#언어에 직접 통한한 기술 집합이다.

LINQ는 쿼리개체 (LINQ to Object), 관계형 데이터베이스(LINQ to SQL), XML(LINQ to XML)에 일관된 쿼리 환경을 제공한다.

LINQ 사용법

배열에 대한 LINQ쿼리 예

using System;
using System.Linq;

public class Program
{
	public static void Main()
	{
		// Data source
		string[] names = {"Bill", "Steve", "James", "Mohan" };
        
		// LINQ Query 
        var myLinqQuery =  from name in names
            			   where name.Contains('a')
            				select name;
        
		// Query execution
        foreach (var name in myLinqQuery)
            Console.Write(name + " ");
	}
}

LINQ 쿼리는 IEnumberable 또는 IQueryable 인터페이스를 구현하는 클래스에 대해 확장 메서드를 사용합니다. Enumerable 및 Queryable은 LINQ 쿼리를 쓰기 위한 확장 메서드를 포함하는 두 개의 정적 클래스입니다.

IEnumable 확장 메서드
Queryable 확장메서드

LINQ 쿼리구문

LINQ query syntax, LINQ Method Syntax 두자리로 쿼리문을 작성 할 수 있다.

LINQ Query Syntax
LINQ Method Syntax

Lambda Expression

람다식은 일부 특수 구문을 사용하여 나타내는 짧게 표현 하는 방법이다.

//Anonymous Method 

using System;
					
public class Program
{
	delegate bool IsTeenAger(Student stud);
	
	public static void Main()
	{
		IsTeenAger isTeenAger = delegate(Student s) { return s.Age > 12 && s.Age < 20; };
		
		Student stud = new Student() { Age = 25 };
		
		Console.WriteLine(isTeenAger(stud));
		
		
	}
}

public class Student{

	public int Id { get; set; }
	public string Name { get; set; }
	public int Age { get; set; }
}
//Func Delegate

using System;
					
public class Program
{
	
	
	public static void Main()
	{
		Func<Student, bool> isStudentTeenAger = s => s.Age > 12 && s.Age < 20;
		
		Student stud = new Student() { Age = 21 };
		
		Console.WriteLine(isStudentTeenAger(stud));
		
		
	}
}

public class Student{

	public int Id { get; set; }
	public string Name { get; set; }
	public int Age { get; set; }
}
//Action Delegate

using System;
					
public class Program
{
	
	
	public static void Main()
	{
		Action<Student> PrintStudentDetail = s => Console.WriteLine("Name: {0}, Age: {1} ", s.Name, s.Age);

		Student std = new Student(){ Name = "Bill", Age=21};

		PrintStudentDetail(std);
		
		
	}
}

public class Student{

	public int Id { get; set; }
	public string Name { get; set; }
	public int Age { get; set; }
}
//Func Delegate IN LINQ Method Syntax

using System;
using System.Linq;
using System.Collections.Generic;

					
public class Program
{
	public static void Main()
	{
		// Student collection
		IList<Student> studentList = new List<Student>() { 
				new Student() { StudentID = 1, StudentName = "John", Age = 13} ,
				new Student() { StudentID = 2, StudentName = "Moin",  Age = 21 } ,
				new Student() { StudentID = 3, StudentName = "Bill",  Age = 18 } ,
				new Student() { StudentID = 4, StudentName = "Ram" , Age = 20} ,
				new Student() { StudentID = 5, StudentName = "Ron" , Age = 15 } 
			};
		
		Func<Student, bool> isStudentTeenAger = s => s.Age > 12 && s.Age < 20;
		
		var teenAgerStudent = studentList.Where(isStudentTeenAger);
							  
		Console.WriteLine("Teen age Students:");
						  
		foreach(Student std in teenAgerStudent){			
			Console.WriteLine(std.StudentName);
		}
	}
}

public class Student{

	public int StudentID { get; set; }
	public string StudentName { get; set; }
	public int Age { get; set; }
	
}

Standard Query Operator

Linq의 표준 쿼리 연산자는 IEnumable<T> and IQueryable<T> 형식의 확장 메서드이다.

IEnumable은 데이터베이스 메모리에서 순차적으로 검색하는 방식으로 메모리 사용량이 많아진다. 

IQueryable은 반대로 쿼리를 작성하여 데이터 검색하는 방식으로 성능과 메모리 사용량을 최적화 한다.

기본쿼리 Query Syntax
기본 쿼리 Method Syntax

where

using System;
using System.Linq;
using System.Collections.Generic;

					
public class Program
{
	public static void Main()
	{
		// Student collection
		IList<Student> studentList = new List<Student>() { 
				new Student() { StudentID = 1, StudentName = "John", Age = 13} ,
				new Student() { StudentID = 2, StudentName = "Moin",  Age = 21 } ,
				new Student() { StudentID = 3, StudentName = "Bill",  Age = 18 } ,
				new Student() { StudentID = 4, StudentName = "Ram" , Age = 20} ,
				new Student() { StudentID = 5, StudentName = "Ron" , Age = 15 } 
			};
		
		// LINQ Query Syntax to find out teenager students
		var teenAgerStudent = from s in studentList
							  where s.Age > 12 && s.Age < 20
							  select s;
        //LINQ Method Syntax
        var tennAgerStudent = studentList.where(s => s.Age > 12 && s.Age < 20);
        
		Console.WriteLine("Teen age Students:");
						  
		foreach(Student std in teenAgerStudent){			
			Console.WriteLine(std.StudentName);
		}
	}
}

public class Student{

	public int StudentID { get; set; }
	public string StudentName { get; set; }
	public int Age { get; set; }
	
}

 

Order by

using System;
using System.Linq;
using System.Collections.Generic;

					
public class Program
{
	public static void Main()
	{
		// Student collection
		IList<Student> studentList = new List<Student>() { 
				new Student() { StudentID = 1, StudentName = "John", Age = 18 } ,
				new Student() { StudentID = 2, StudentName = "Steve",  Age = 15 } ,
				new Student() { StudentID = 3, StudentName = "Bill",  Age = 25 } ,
				new Student() { StudentID = 4, StudentName = "Ram" , Age = 20 } ,
				new Student() { StudentID = 5, StudentName = "Ron" , Age = 19 } 
			};
		
		var orderByResult = from s in studentList
                   orderby s.StudentName //Sorts the studentList collection in ascending order
                   select s;

		var orderByDescendingResult = from s in studentList //Sorts the studentList collection in descending order
                   orderby s.StudentName descending
                   select s;
		
		Console.WriteLine("Ascending Order:");
		
		foreach (var std in orderByResult)
        	Console.WriteLine(std.StudentName);
		
		Console.WriteLine("Descending Order:");
		
		foreach (var std in orderByDescendingResult)
        	Console.WriteLine(std.StudentName);
		
	}
		
}

public class Student{

	public int StudentID { get; set; }
	public string StudentName { get; set; }
	public int Age { get; set; }
	
}

 

GroupBy

using System;
using System.Linq;
using System.Collections.Generic;

					
public class Program
{
	public static void Main()
	{
		// Student collection
		IList<Student> studentList = new List<Student>() { 
				new Student() { StudentID = 1, StudentName = "John", Age = 18 } ,
				new Student() { StudentID = 2, StudentName = "Steve",  Age = 21 } ,
				new Student() { StudentID = 3, StudentName = "Bill",  Age = 18 } ,
				new Student() { StudentID = 4, StudentName = "Ram" , Age = 20 } ,
				new Student() { StudentID = 5, StudentName = "Ron" , Age = 21 } 
			};
		
        //Query syntax
		var groupedResult = from s in studentList
                    group s by s.Age;
        //method syntax
        var groupedResult = studentList.GroupBy(s => s.Age);

		//iterate each group        
		foreach (var ageGroup in groupedResult)
		{
			Console.WriteLine("Age Group: {0}", ageGroup.Key); //Each group has a key 
					 
			foreach(Student s in ageGroup) // Each group has inner collection
				Console.WriteLine("Student Name: {0}", s.StudentName);
		}
		
	}
		
}

public class Student{

	public int StudentID { get; set; }
	public string StudentName { get; set; }
	public int Age { get; set; }
	
}

Join

using System;
using System.Linq;
using System.Collections.Generic;

					
public class Program
{
	public static void Main()
	{
		// Student collection
		IList<Student> studentList = new List<Student>() { 
				new Student() { StudentID = 1, StudentName = "John", Age = 18, StandardID = 1 } ,
				new Student() { StudentID = 2, StudentName = "Steve",  Age = 21, StandardID = 1 } ,
				new Student() { StudentID = 3, StudentName = "Bill",  Age = 18, StandardID = 2 } ,
				new Student() { StudentID = 4, StudentName = "Ram" , Age = 20, StandardID = 2 } ,
				new Student() { StudentID = 5, StudentName = "Ron" , Age = 21 } 
			};
		
		IList<Standard> standardList = new List<Standard>() { 
				new Standard(){ StandardID = 1, StandardName="Standard 1"},
				new Standard(){ StandardID = 2, StandardName="Standard 2"},
				new Standard(){ StandardID = 3, StandardName="Standard 3"}
			};
		
		var innerJoinResult = studentList.Join(// outer sequence 
                      standardList,  // inner sequence 
                      student => student.StandardID,    // outerKeySelector
                      standard => standard.StandardID,  // innerKeySelector
                      (student, standard) => new  // result selector
                                    {
                                        StudentName = student.StudentName,
                                        StandardName = standard.StandardName
                                    });

		foreach (var obj in innerJoinResult)
		{
			
			Console.WriteLine("{0} - {1}", obj.StudentName, obj.StandardName);
		}
		
	}
		
}

public class Student{

	public int StudentID { get; set; }
	public string StudentName { get; set; }
	public int Age { get; set; }
	public int StandardID { get; set; }
}

public class Standard{

	public int StandardID { get; set; }
	public string StandardName { get; set; }
}

GroupJoin

using System;
using System.Linq;
using System.Collections.Generic;

					
public class Program
{
	public static void Main()
	{
		// Student collection
		IList<Student> studentList = new List<Student>() { 
				new Student() { StudentID = 1, StudentName = "John", Age = 18, StandardID = 1 } ,
				new Student() { StudentID = 2, StudentName = "Steve",  Age = 21, StandardID = 1 } ,
				new Student() { StudentID = 3, StudentName = "Bill",  Age = 18, StandardID = 2 } ,
				new Student() { StudentID = 4, StudentName = "Ram" , Age = 20, StandardID = 2 } ,
				new Student() { StudentID = 5, StudentName = "Ron" , Age = 21 } 
			};
		
		IList<Standard> standardList = new List<Standard>() { 
				new Standard(){ StandardID = 1, StandardName="Standard 1"},
				new Standard(){ StandardID = 2, StandardName="Standard 2"},
				new Standard(){ StandardID = 3, StandardName="Standard 3"}
			};
		
		var groupJoin = from std in standardList 
                      join s in studentList 
                      on std.StandardID equals s.StandardID
                          into studentGroup
                      select new { 
                              Students = studentGroup , 
                              StandardName = std.StandardName 
                          };


		foreach (var item in groupJoin)
		{ 
			Console.WriteLine(item.StandardName );
			
			foreach(var stud in item.Students)
				Console.WriteLine(stud.StudentName);
		}
		
	}
		
}

public class Student{

	public int StudentID { get; set; }
	public string StudentName { get; set; }
	public int Age { get; set; }
	public int StandardID { get; set; }
}

public class Standard{

	public int StandardID { get; set; }
	public string StandardName { get; set; }
}

Select

using System;
using System.Linq;
using System.Collections.Generic;

					
public class Program
{
	public static void Main()
	{
		IList<Student> studentList = new List<Student>() { 
			new Student() { StudentID = 1, StudentName = "John", Age = 13 } ,
			new Student() { StudentID = 2, StudentName = "Moin",  Age = 21 } ,
			new Student() { StudentID = 3, StudentName = "Bill",  Age = 18 } ,
			new Student() { StudentID = 4, StudentName = "Ram" , Age = 20 } ,
			new Student() { StudentID = 5, StudentName = "Ron" , Age = 15 } 
		};
		
		// returns collection of anonymous objects with Name and Age property
		var selectResult = from s in studentList
						   select new { Name = "Mr. " + s.StudentName, Age = s.Age }; 
		
		// iterate selectResult
		foreach (var item in selectResult)
			Console.WriteLine("Student Name: {0}, Age: {1}", item.Name, item.Age);
	}
}

public class Student{

	public int StudentID { get; set; }
	public string StudentName { get; set; }
	public int Age { get; set; }
}

All

using System;
using System.Linq;
using System.Collections.Generic;

					
public class Program
{
	public static void Main()
	{
		IList<Student> studentList = new List<Student>() { 
			new Student() { StudentID = 1, StudentName = "John", Age = 13 } ,
			new Student() { StudentID = 2, StudentName = "Moin",  Age = 21 } ,
			new Student() { StudentID = 3, StudentName = "Bill",  Age = 18 } ,
			new Student() { StudentID = 4, StudentName = "Ram" , Age = 20 } ,
			new Student() { StudentID = 5, StudentName = "Ron" , Age = 15 } 
		};		
		
		// checks whether all the students are teenagers    
		bool areAllStudentsTeenAger = studentList.All(s => s.Age > 12 && s.Age < 20);
		
		
		Console.WriteLine(areAllStudentsTeenAger);
	}
}

public class Student{

	public int StudentID { get; set; }
	public string StudentName { get; set; }
	public int Age { get; set; }
}

 

First & FirstOrDefault

using System;
using System.Linq;
using System.Collections.Generic;

public class Program
{
	public static void Main()
	{
		IList<int> intList = new List<int>() { 7, 10, 21, 30, 45, 50, 87 };
		IList<string> strList = new List<string>() { null, "Two", "Three", "Four", "Five" };
		IList<string> emptyList = new List<string>();
				
		Console.WriteLine("1st Element in intList: {0}", intList.FirstOrDefault());
		
		Console.WriteLine("1st Even Element in intList: {0}", intList.FirstOrDefault(i => i % 2 == 0));
		
		Console.WriteLine("1st Element in strList: {0}", strList.FirstOrDefault());
		
		Console.WriteLine("1st Element in emptyList: {0}", emptyList.FirstOrDefault());
		
	}
}

distinct

using System;
using System.Linq;					
using System.Collections.Generic;


public class Program
{
	public static void Main()
	{
		IList<Student> studentList = new List<Student>() { 
			new Student() { StudentID = 1, StudentName = "John", Age = 18 } ,
			new Student() { StudentID = 2, StudentName = "Steve",  Age = 15 } ,
			new Student() { StudentID = 3, StudentName = "Bill",  Age = 25 } ,
			new Student() { StudentID = 3, StudentName = "Bill",  Age = 25 } ,
			new Student() { StudentID = 3, StudentName = "Bill",  Age = 25 } ,
			new Student() { StudentID = 3, StudentName = "Bill",  Age = 25 } ,
			new Student() { StudentID = 5, StudentName = "Ron" , Age = 19 } 
	    };


		var distinctStudents = studentList.Distinct(new StudentComparer()); 
		
		foreach(var std in distinctStudents)
			Console.WriteLine(std.StudentName);

	}
}

public class Student 
{
    public int StudentID { get; set; }
    public string StudentName { get; set; }
    public int Age { get; set; }
}

public class StudentComparer : IEqualityComparer<Student>
{
    public bool Equals(Student x, Student y)
    {
        if (x.StudentID == y.StudentID 
                && x.StudentName.ToLower() == y.StudentName.ToLower() )
            return true;

        return false;
    }

    public int GetHashCode(Student obj)
    {
        return obj.StudentID.GetHashCode();
    }
}

 

-출처 : https://www.tutorialsteacher.com/linq  https://aspdotnet.tistory.com/3011 -