다음을 통해 공유


LINQ를 통한 데이터 변환

업데이트: 2007년 11월

LINQ(통합 언어 쿼리)는 데이터를 검색할 뿐 아니라 데이터를 변환하는 강력한 도구입니다. LINQ 쿼리를 사용하면 소스 시퀀스를 입력으로 사용하고 다양한 방식으로 수정하여 새 출력 시퀀스를 만들 수 있습니다. 0% your edit You can modify the sequence itself without modifying the elements themselves by sorting and grouping. 정렬 및 그룹화하여 요소 자체를 수정하지 않고도 시퀀스를 수정할 수 있습니다. 그러나 LINQ 쿼리의 가장 강력한 기능은 새 형식을 만드는 기능입니다. 이 작업은 select 절에서 수행됩니다. 예를 들어, 아래와 같은 작업을 수행할 수 있습니다.

  • 여러 개의 입력 시퀀스를 새 형식의 단일 출력 시퀀스로 병합합니다.

  • 요소가 소스 시퀀스에 있는 각 요소의 한 속성만으로 또는 여러 속성으로 구성된 출력 시퀀스를 만듭니다.

  • 요소가 소스 데이터에서 수행된 작업 결과로 구성된 출력 시퀀스를 만듭니다.

  • 다른 형식으로 출력 시퀀스를 만듭니다. 예를 들어 SQL 행 또는 텍스트 파일에서 XML로 데이터를 변환할 수 있습니다.

다음은 몇 가지 예일 뿐입니다. 물론 동일한 쿼리에서 이러한 변환을 다양한 방식으로 결합할 수 있습니다. 한 쿼리의 출력 시퀀스를 새 쿼리의 입력 시퀀스로 사용할 수도 있습니다.

여러 입력을 하나의 출력 시퀀스로 결합

LINQ 쿼리를 사용하여 둘 이상의 입력 시퀀스의 요소를 포함하는 출력 시퀀스를 만들 수 있습니다. 다음 예제에서는 두 개의 메모리 내 데이터 구조를 결합하는 방법을 보여 주지만, XML이나 SQL 또는 DataSet 소스의 데이터를 결합하는 경우에도 동일한 원칙을 적용할 수 있습니다. 다음 두 개의 클래스 형식이 있다고 가정합니다.

class Student
{
    public string First { get; set; }
    public string Last {get; set;}
    public int ID { get; set; }
    public string Street { get; set; }
    public string City { get; set; }
    public List<int> Scores;
}

class Teacher
{
    public string First { get; set; }
    public string Last { get; set; }
    public int ID { get; set; } 
    public string City { get; set; }
}

다음 예제에서는 쿼리를 보여 줍니다.

class DataTransformations
{
    static void Main()
    {
        // Create the first data source.
        List<Student> students = new List<Student>()
        {
            new Student {First="Svetlana",
                Last="Omelchenko", 
                ID=111, 
                Street="123 Main Street",
                City="Seattle",
                Scores= new List<int> {97, 92, 81, 60}},
            new Student {First="Claire",
                Last="O’Donnell", 
                ID=112,
                Street="124 Main Street",
                City="Redmond",
                Scores= new List<int> {75, 84, 91, 39}},
            new Student {First="Sven",
                Last="Mortensen",
                ID=113,
                Street="125 Main Street",
                City="Lake City",
                Scores= new List<int> {88, 94, 65, 91}},
        };

        // Create the second data source.
        List<Teacher> teachers = new List<Teacher>()
        {                
            new Teacher {First="Ann", Last="Beebe", ID=945, City = "Seattle"},
            new Teacher {First="Alex", Last="Robinson", ID=956, City = "Redmond"},
            new Teacher {First="Michiyo", Last="Sato", ID=972, City = "Tacoma"}
        };

        // Create the query.
        var peopleInSeattle = (from student in students
                    where student.City == "Seattle"
                    select student.Last)
                    .Concat(from teacher in teachers
                            where teacher.City == "Seattle"
                            select teacher.Last);

        Console.WriteLine("The following students and teachers live in Seattle:");
        // Execute the query.
        foreach (var person in peopleInSeattle)
        {
            Console.WriteLine(person);
        }

        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }
}
/* Output:
    The following students and teachers live in Seattle:
    Omelchenko
    Beebe
 */

자세한 내용은 join 절(C# 참조)select 절(C# 참조)을 참조하십시오.

각 소스 요소의 하위 집합 선택

소스 시퀀스에 있는 각 요소의 하위 집합을 선택하는 두 가지 기본 방법이 있습니다.

  1. 소스 요소의 한 멤버만 선택하려면 점 작업을 사용합니다. 다음 예제에서는 Customer 개체에 City라는 문자열을 포함하는 여러 public 속성이 있다고 가정합니다. 실행할 때 이 쿼리는 문자열의 출력 시퀀스를 생성합니다.

    var query = from cust in Customers
                select cust.City;
    
  2. 소스 요소의 속성을 둘 이상 포함하는 요소를 만들려면 명명된 개체나 익명 형식으로 개체 이니셜라이저를 사용할 수 있습니다. 다음 예제에서는 익명 형식을 사용하여 각 Customer 요소의 두 속성을 캡슐화하는 방법을 보여 줍니다.

    var query = from cust in Customer
                select new {Name = cust.Name, City = cust.City};
    

자세한 내용은 개체 및 컬렉션 이니셜라이저(C# 프로그래밍 가이드)익명 형식(C# 프로그래밍 가이드)을 참조하십시오.

메모리 내부 개체를 XML로 변환

LINQ 쿼리를 사용하면 메모리 내부 데이터 구조, SQL 데이터베이스, ADO.NET 데이터 집합 및 XML 스트림 또는 문서 간에 데이터를 쉽게 변환할 수 있습니다. 다음 예제에서는 메모리 내부 데이터 구조의 개체를 XML 요소로 변환합니다.

class XMLTransform
{
    static void Main()
    {            
        // Create the data source by using a collection initializer.
        List<Student> students = new List<Student>()
        {
            new Student {First="Svetlana", Last="Omelchenko", ID=111, Scores = new List<int>{97, 92, 81, 60}},
            new Student {First="Claire", Last="O’Donnell", ID=112, Scores = new List<int>{75, 84, 91, 39}},
            new Student {First="Sven", Last="Mortensen", ID=113, Scores = new List<int>{88, 94, 65, 91}},
        };

        // Create the query.
        var studentsToXML = new XElement("Root",
            from student in students
            let x = String.Format("{0},{1},{2},{3}", student.Scores[0],
                    student.Scores[1], student.Scores[2], student.Scores[3])
            select new XElement("student",
                       new XElement("First", student.First),
                       new XElement("Last", student.Last),
                       new XElement("Scores", x)
                    ) // end "student"
                ); // end "Root"

        // Execute the query.
        Console.WriteLine(studentsToXML);

        // Keep the console open in debug mode.
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }
}

이 코드는 다음과 같은 XML 출력을 생성합니다.

< Root>
  <student>
    <First>Svetlana</First>
    <Last>Omelchenko</Last>
    <Scores>97,92,81,60</Scores>
  </student>
  <student>
    <First>Claire</First>
    <Last>O'Donnell</Last>
    <Scores>75,84,91,39</Scores>
  </student>
  <student>
    <First>Sven</First>
    <Last>Mortensen</Last>
    <Scores>88,94,65,91</Scores>
  </student>
</Root>

자세한 내용은 C#에서 XML 트리 만들기(LINQ to XML)를 참조하십시오.

소스 요소에서 작업 수행

출력 시퀀스에 소스 시퀀스의 요소나 요소 속성이 포함되지 않을 수도 있습니다. 대신 출력은 소스 요소를 입력 인수로 사용하여 계산된 값의 시퀀스일 수 있습니다. 아래의 단순한 쿼리를 실행하면 값이 double 형식 요소의 소스 시퀀스에 기초한 계산을 나타내는 문자열 시퀀스가 출력됩니다.

참고:

쿼리가 다른 도메인으로 변환되는 경우 쿼리 식에서 메서드를 호출할 수 없습니다. 예를 들어 SQL Server에 해당 컨텍스트가 없으므로 LINQ to SQL에서 일반 C# 메서드를 호출할 수는 없습니다. 그러나 저장 프로시저를 메서드에 매핑하고 호출할 수 있습니다. 자세한 내용은 저장 프로시저(LINQ to SQL)를 참조하십시오.

class FormatQuery
{
    static void Main()
    {            
        // Data source.
        double[] radii = { 1, 2, 3 };

        // Query.
        IEnumerable<string> query =
            from rad in radii
            select String.Format("Area = {0}", (rad * rad) * 3.14);

        // Query execution. 
        foreach (string s in query)
            Console.WriteLine(s);

        // Keep the console open in debug mode.
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }
}
/* Output:
    Area = 3.14
    Area = 12.56
    Area = 28.26
*/

참고 항목

개념

LINQ 쿼리 식(C# 프로그래밍 가이드)

참조

select 절(C# 참조)

기타 리소스

LINQ(통합 언어 쿼리)

LINQ to SQL

LINQ to DataSet

LINQ to XML