C#/LINQ

[C#]LINQ Select절

DevStory 2022. 7. 10.

Select문

LINQ의 Select문은 SQL의 Select문과 동일합니다. Select문은 데이터의 모든 항목을 추출할 것인지 특정 항목만 추출할 것인지 설정할 수 있는 문법입니다.

 

Select문은 질의 구문(Query Syntax), 메서드 구문(Method Syntax) 둘 다 존재합니다. 따라서, 이번 포스팅에서는 질의 구문, 메서드 구문에서 Select문을 사용하는 방법을 소개합니다.


예제 1. 기본 사용 방법

다음 예제는 질의 구문과 메서드 구문을 사용하여 데이터 원본에서 모든 항목 추출합니다.

class Person
{
  public int ID { get; set; }
  public string Name { get; set; }
  public int Age { get; set; }

  public override string ToString()
  {
    return "ID: " + ID + ", Name: " + Name + ", Age: " + Age;
  }
}

class Program
{
  static void Main(string[] args)
  {
    List<Person> person = new List<Person>
    {
      new Person() { ID = 100, Name = "Bob",     Age = 20},
      new Person() { ID = 200, Name = "Tim",     Age = 25},
      new Person() { ID = 300, Name = "Charles", Age = 30},
      new Person() { ID = 400, Name = "Nick",    Age = 35},
      new Person() { ID = 500, Name = "John",    Age = 40},
      new Person() { ID = 500, Name = "Sam" ,    Age = 45}
    };

    // 1. 질의 구문(Query Syntax)
    List<Person> linqQueryResult = (from   obj in person
                                    select obj).ToList();

    // 2. 메서드 구문(Method Syntax)
    List <Person> linqMethodResult = person.Select(item => item).ToList();

    Console.WriteLine("질의 구문");
    foreach (Person obj in linqQueryResult)
      Console.WriteLine(obj.ToString());

    Console.WriteLine("\n메서드 구문");
    foreach (Person obj in linqMethodResult)
      Console.WriteLine(obj.ToString());
  }
}

[실행 결과]

질의 구문
ID: 100, Name: Bob, Age: 20
ID: 200, Name: Tim, Age: 25
ID: 300, Name: Charles, Age: 30
ID: 400, Name: Nick, Age: 35
ID: 500, Name: John, Age: 40
ID: 500, Name: Sam, Age: 45

메서드 구문
ID: 100, Name: Bob, Age: 20
ID: 200, Name: Tim, Age: 25
ID: 300, Name: Charles, Age: 30
ID: 400, Name: Nick, Age: 35
ID: 500, Name: John, Age: 40
ID: 500, Name: Sam, Age: 45

예제 2. 단일 프로퍼티 추출

다음 내용은 Select문에서 특정 프로퍼티를 추출하는 경우 참고해야 하는 내용입니다.

// 1. 질의 구문(Query Syntax)
List<Person> linqQueryResult = (from   obj in person
                                select obj.ID).ToList();

// 2. 메서드 구문(Method Syntax)
List <Person> linqMethodResult = person.Select(item => item.ID).ToList();

[에러 내용]

Select문에서 특정 프로퍼티를 추출 후 ToList() 메서드를 호출하면 컴파일 에러가 발생합니다. 클래스 Person의 ID 프로퍼티는 int 타입이므로 List<Person>으로 변환할 수 없다는 의미입니다.

 

따라서, 다음 예제처럼 추출하는 프로퍼티와 동일한 타입의 List로 질의 결과를 반환받을 수 있습니다.

class Person
{
  public int ID { get; set; }
  public string Name { get; set; }
  public int Age { get; set; }

  public override string ToString()
  {
    return "ID: " + ID + ", Name: " + Name + ", Age: " + Age;
  }
}

class Program
{
  static void Main(string[] args)
  {
    List<Person> person = new List<Person>
    {
      new Person() { ID = 100, Name = "Bob",     Age = 20},
      new Person() { ID = 200, Name = "Tim",     Age = 25},
      new Person() { ID = 300, Name = "Charles", Age = 30},
      new Person() { ID = 400, Name = "Nick",    Age = 35},
      new Person() { ID = 500, Name = "John",    Age = 40},
      new Person() { ID = 500, Name = "Sam" ,    Age = 45}
    };

    // 1. 질의 구문(Query Syntax)
    List<int> linqQueryResult = (from   obj in person
                                 select obj.ID).ToList();

    // 2. 메서드 구문(Method Syntax)
    List <int> linqMethodResult = person.Select(item => item.ID).ToList();

    Console.WriteLine("질의 구문");
    foreach (int id in linqQueryResult)
      Console.WriteLine(id);

    Console.WriteLine("\n메서드 구문");
    foreach (int id in linqMethodResult)
      Console.WriteLine(id);
  }
}

[실행 결과]

질의 구문
100
200
300
400
500
500

메서드 구문
100
200
300
400
500
500

예제 3. 여러 프로퍼티 추출

여러 프로퍼티를 추출하는 방법은 단일 프로퍼티가 아니므로 List<Person>으로 변환할 수 있습니다.

 

다음 예제는 ID와 Name 프로퍼티를 추출합니다. Age 프로퍼티는 필요 없으며, LINQ 구문에서 새로운 객체를 생성하는 방법으로 여러 프로퍼티를 추출할 수 있습니다.

class Person
{
  public int ID { get; set; }
  public string Name { get; set; }
  public int Age { get; set; }

  public override string ToString()
  {
    return "ID: " + ID + ", Name: " + Name + ", Age: " + Age;
  }
}

class Program
{
  static void Main(string[] args)
  {
    List<Person> person = new List<Person>
    {
      new Person() { ID = 100, Name = "Bob",     Age = 20},
      new Person() { ID = 200, Name = "Tim",     Age = 25},
      new Person() { ID = 300, Name = "Charles", Age = 30},
      new Person() { ID = 400, Name = "Nick",    Age = 35},
      new Person() { ID = 500, Name = "John",    Age = 40},
      new Person() { ID = 500, Name = "Sam" ,    Age = 45}
    };

    // 1. 질의 구문(Query Syntax)
    List<Person> linqQueryResult = (from   obj in person
                                    select new Person()
                                    {
                                      ID = obj.ID,
                                      Name = obj.Name
                                    }).ToList();

    // 2. 메서드 구문(Method Syntax)
    List <Person> linqMethodResult = person.Select(item => new Person()
    {
      ID = item.ID,
      Name = item.Name
    }).ToList();

    Console.WriteLine("질의 구문");
    foreach (Person obj in linqQueryResult)
      Console.WriteLine(obj.ToString());

    Console.WriteLine("\n메서드 구문");
    foreach (Person obj in linqMethodResult)
      Console.WriteLine(obj.ToString());
  }
}

[실행 결과]

질의 구문
ID: 100, Name: Bob, Age: 0
ID: 200, Name: Tim, Age: 0
ID: 300, Name: Charles, Age: 0
ID: 400, Name: Nick, Age: 0
ID: 500, Name: John, Age: 0
ID: 500, Name: Sam, Age: 0

메서드 구문
ID: 100, Name: Bob, Age: 0
ID: 200, Name: Tim, Age: 0
ID: 300, Name: Charles, Age: 0
ID: 400, Name: Nick, Age: 0
ID: 500, Name: John, Age: 0
ID: 500, Name: Sam, Age: 0

ID와 Name 프로퍼티만 추출되었으며, Age 프로퍼티는 기본 값인 0으로 할당됩니다.


예제 4. 타입 변경

여러 프로퍼티를 추출하는 방법을 응용한다면 반환 타입을 변경할 수 있습니다. 다음 예제는 데이터는 List<Person> 객체에서 추출하지만, LINQ 질의 결과는 List<PersonCopy> 객체에 할당됩니다.

class Person
{
  public int ID { get; set; }
  public string Name { get; set; }
  public int Age { get; set; }

  public override string ToString()
  {
    return "ID: " + ID + ", Name: " + Name + ", Age: " + Age;
  }
}

class PersonCopy
{
  public int ID { get; set; }
  public string Name { get; set; }
  public int Age { get; set; }

  public override string ToString()
  {
    return "ID: " + ID + ", Name: " + Name + ", Age: " + Age;
  }
}

class Program
{
  static void Main(string[] args)
  {
    List<Person> person = new List<Person>
    {
      new Person() { ID = 100, Name = "Bob",     Age = 20},
      new Person() { ID = 200, Name = "Tim",     Age = 25},
      new Person() { ID = 300, Name = "Charles", Age = 30},
      new Person() { ID = 400, Name = "Nick",    Age = 35},
      new Person() { ID = 500, Name = "John",    Age = 40},
      new Person() { ID = 500, Name = "Sam" ,    Age = 45}
    };

    // 1. 질의 구문(Query Syntax);
    List<PersonCopy> linqQueryResult = (from obj in person
                                        select new PersonCopy() // Person -> PersonCopy로 변경
                                        {
                                            ID = obj.ID,
                                            Name = obj.Name
                                        }).ToList();

    // 2. 메서드 구문(Method Syntax)
    List <PersonCopy> linqMethodResult = person
      .Select(item => new PersonCopy() // Person -> PersonCopy로 변경
      {
        ID = item.ID,
        Name = item.Name
      }).ToList();

    Console.WriteLine("질의 구문");
    foreach (PersonCopy obj in linqQueryResult) // Person -> PersonCopy로 변경
      Console.WriteLine(obj.ToString());

    Console.WriteLine("\n메서드 구문");
    foreach (PersonCopy obj in linqMethodResult) // Person -> PersonCopy로 변경
      Console.WriteLine(obj.ToString());
  }
}

[실행 결과]

질의 구문
ID: 100, Name: Bob, Age: 0
ID: 200, Name: Tim, Age: 0
ID: 300, Name: Charles, Age: 0
ID: 400, Name: Nick, Age: 0
ID: 500, Name: John, Age: 0
ID: 500, Name: Sam, Age: 0

메서드 구문
ID: 100, Name: Bob, Age: 0
ID: 200, Name: Tim, Age: 0
ID: 300, Name: Charles, Age: 0
ID: 400, Name: Nick, Age: 0
ID: 500, Name: John, Age: 0
ID: 500, Name: Sam, Age: 0

예제 5. 프로퍼티 값 변경

Select문에서 프로퍼티의 값을 변경할 수 있습니다. 

- 이름을 소문자로 변경

- Age = Age * 10

class Person
{
  public int ID { get; set; }
  public string Name { get; set; }
  public int Age { get; set; }

  public override string ToString()
  {
    return "ID: " + ID + ", Name: " + Name + ", Age: " + Age;
  }
}

class Program
{
  static void Main(string[] args)
  {
    List<Person> person = new List<Person>
    {
      new Person() { ID = 100, Name = "Bob",     Age = 20},
      new Person() { ID = 200, Name = "Tim",     Age = 25},
      new Person() { ID = 300, Name = "Charles", Age = 30},
      new Person() { ID = 400, Name = "Nick",    Age = 35},
      new Person() { ID = 500, Name = "John",    Age = 40},
      new Person() { ID = 500, Name = "Sam" ,    Age = 45}
    };

    // 1. 질의 구문(Query Syntax)
    List<Person> linqQueryResult = (from obj in person
                                    select new Person()
                                    {
                                      ID = obj.ID,
                                      Name = obj.Name.ToLower(),
                                      Age = obj.Age * 10
                                    }).ToList();

    // 2. 메서드 구문(Method Syntax)
    List <Person> linqMethodResult = person.Select(item => new Person()
    {
      ID = item.ID,
      Name = item.Name.ToLower(),
      Age = item.Age * 10
    }).ToList();

    Console.WriteLine("질의 구문");
    foreach (Person obj in linqQueryResult)
      Console.WriteLine(obj.ToString());

    Console.WriteLine("\n메서드 구문");
    foreach (Person obj in linqMethodResult)
      Console.WriteLine(obj.ToString());
  }
}

[실행 결과]

질의 구문
ID: 100, Name: bob, Age: 200
ID: 200, Name: tim, Age: 250
ID: 300, Name: charles, Age: 300
ID: 400, Name: nick, Age: 350
ID: 500, Name: john, Age: 400
ID: 500, Name: sam, Age: 450

메서드 구문
ID: 100, Name: bob, Age: 200
ID: 200, Name: tim, Age: 250
ID: 300, Name: charles, Age: 300
ID: 400, Name: nick, Age: 350
ID: 500, Name: john, Age: 400
ID: 500, Name: sam, Age: 450
반응형

'C# > LINQ' 카테고리의 다른 글

[C#]LINQ 데이터 필터링 방법 - Where절  (0) 2022.07.10
[C#]LINQ SelectMany 메서드  (0) 2022.07.10
[C#]LINQ 확장 메서드  (0) 2022.07.10
[C#]LINQ와 IEnumerable, IQueryable 인터페이스  (0) 2022.07.10
[C#]LINQ 중복 제거  (0) 2022.07.10

댓글