다음을 통해 공유


쿼리에서 DataTable 만들기(LINQ to DataSet)

데이터 바인딩은 개체의 일반적인 용도입니다 DataTable . 이 메서드는 CopyToDataTable 쿼리 결과를 가져와 데이터를 데이터 바인딩에 사용할 수 있는 데이터로 DataTable복사합니다. 데이터 작업이 수행되면 새 DataTable 작업이 원본 DataTable으로 다시 병합됩니다.

이 메서드는 CopyToDataTable 다음 프로세스를 사용하여 쿼리에서 DataTable를 만듭니다.

  1. CopyToDataTable 메서드는 DataTable 인터페이스를 구현하는 DataTable 객체인 원본 테이블에서 IQueryable<T>을 복제합니다. 원본은 IEnumerable 일반적으로 LINQ to DataSet 식 또는 메서드 쿼리에서 시작됩니다.

  2. 복제 DataTable 된 스키마는 원본 테이블에서 열거된 DataRow 첫 번째 개체의 열에서 작성되며 복제된 테이블의 이름은 "query"라는 단어가 추가된 원본 테이블의 이름입니다.

  3. 원본 테이블의 각 행에 대해 행의 내용이 새 DataRow 개체에 복사된 다음 복제된 테이블에 삽입됩니다. RowStateRowError 속성은 복사 작업 전체에서 유지됩니다. ArgumentException는 소스의 DataRow 개체가 서로 다른 테이블에서 온 경우 던져집니다.

  4. 입력 쿼리 가능 테이블의 모든 DataTable 개체가 복사된 후에 복제 DataRow 된 항목이 반환됩니다. 소스 시퀀스에 개체가 없 DataRow 으면 메서드는 빈 DataTable개체를 반환합니다.

메서드를 CopyToDataTable 호출하면 원본 테이블에 바인딩된 쿼리가 실행됩니다.

메서드가 원본 테이블의 CopyToDataTable 행에서 null 참조 또는 nullable 값 형식을 발견하면 값을 . Value로 바꿉니다. 이러한 방식으로 null 값은 반환 DataTable된 값에서 올바르게 처리됩니다.

참고: 메서드는 CopyToDataTable 여러 DataTable 개체 또는 DataSet 개체에서 행을 반환할 수 있는 쿼리를 입력으로 허용합니다. 메서드는 CopyToDataTable 원본 DataTable 또는 DataSet 개체의 데이터를 반환된 DataTable로 복사하지만 속성은 복사하지 않습니다. 반환 DataTable된 속성(예: LocaleTableName)을 명시적으로 설정해야 합니다.

다음 예제에서는 SalesOrderHeader 테이블을 쿼리하여 2001년 8월 8일 이후의 주문을 확인하고, 해당 쿼리에서 CopyToDataTable 메서드를 사용하여 DataTable를 생성합니다. 먼저 DataTableBindingSource에 바인딩되고, BindingSource는 에 대한 프록시 역할을 합니다.

// Bind the System.Windows.Forms.DataGridView object
// to the System.Windows.Forms.BindingSource object.
dataGridView.DataSource = bindingSource;

// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);

DataTable orders = ds.Tables["SalesOrderHeader"];

// Query the SalesOrderHeader table for orders placed
// after August 8, 2001.
IEnumerable<DataRow> query =
    from order in orders.AsEnumerable()
    where order.Field<DateTime>("OrderDate") > new DateTime(2001, 8, 1)
    select order;

// Create a table from the query.
DataTable boundTable = query.CopyToDataTable<DataRow>();

// Bind the table to a System.Windows.Forms.BindingSource object,
// which acts as a proxy for a System.Windows.Forms.DataGridView object.
bindingSource.DataSource = boundTable;
' Bind the System.Windows.Forms.DataGridView object
' to the System.Windows.Forms.BindingSource object.
dataGridView.DataSource = bindingSource

' Fill the DataSet.
Dim ds As New DataSet()
ds.Locale = CultureInfo.InvariantCulture
' See the FillDataSet method in the Loading Data Into a DataSet topic.
FillDataSet(ds)

Dim orders As DataTable = ds.Tables("SalesOrderHeader")

' Query the SalesOrderHeader table for orders placed
'  after August 8, 2001.
Dim query = _
    From order In orders.AsEnumerable() _
    Where order.Field(Of DateTime)("OrderDate") > New DateTime(2001, 8, 1) _
    Select order

' Create a table from the query.
Dim boundTable As DataTable = query.CopyToDataTable()

' Bind the table to a System.Windows.Forms.BindingSource object,
' which acts as a proxy for a System.Windows.Forms.DataGridView object.
bindingSource.DataSource = boundTable

사용자 지정 CopyToDataTable<T> 메서드 만들기

기존 CopyToDataTable 메서드는 제네릭 매개 변수 IEnumerable<T> 가 형식TDataRow 원본에서만 작동합니다. 유용하지만 테이블 조인을 수행하는 쿼리 또는 익명 형식을 반환하는 쿼리에서 스칼라 형식 시퀀스에서 테이블을 만들 수는 없습니다. 스칼라 또는 익명 형식 시퀀스에서 테이블을 로드하는 두 개의 사용자 지정 CopyToDataTable 메서드를 구현하는 방법에 대한 예제는 방법: 제네릭 형식 T가 DataRow가 아닌 CopyToDataTable<T> 구현을 참조하세요.

이 섹션의 예제에서는 다음 사용자 지정 형식을 사용합니다.

public class Item
{
    public int Id { get; set; }
    public double Price { get; set; }
    public string Genre { get; set; }
}

public class Book : Item
{
    public string Author { get; set; }
}

public class Movie : Item
{
    public string Director { get; set; }
}
Public Class Item
    Private _Id As Int32
    Private _Price As Double
    Private _Genre As String

    Public Property Id() As Int32
        Get
            Return Id
        End Get
        Set(ByVal value As Int32)
            _Id = value
        End Set
    End Property

    Public Property Price() As Double
        Get
            Return _Price
        End Get
        Set(ByVal value As Double)
            _Price = value
        End Set
    End Property

    Public Property Genre() As String
        Get
            Return _Genre
        End Get
        Set(ByVal value As String)
            _Genre = value
        End Set
    End Property

End Class
Public Class Book
    Inherits Item
    Private _Author As String
    Public Property Author() As String
        Get
            Return _Author
        End Get
        Set(ByVal value As String)
            _Author = value
        End Set
    End Property
End Class

Public Class Movie
    Inherits Item
    Private _Director As String
    Public Property Director() As String
        Get
            Return _Director
        End Get
        Set(ByVal value As String)
            _Director = value
        End Set
    End Property

End Class

예시

이 예제는 SalesOrderHeader 테이블과 SalesOrderDetail 테이블 간 조인을 수행하여 8월의 온라인 주문을 가져오고 쿼리에서 테이블을 만듭니다.

// Fill the DataSet.
var ds = new DataSet
{
    Locale = CultureInfo.InvariantCulture
};
FillDataSet(ds);

DataTable orders = ds.Tables["SalesOrderHeader"];
DataTable details = ds.Tables["SalesOrderDetail"];

var query =
    from order in orders.AsEnumerable()
    join detail in details.AsEnumerable()
    on order.Field<int>("SalesOrderID") equals
        detail.Field<int>("SalesOrderID")
    where order.Field<bool>("OnlineOrderFlag")
        && order.Field<DateTime>("OrderDate").Month == 8
    select new
    {
        SalesOrderID =
            order.Field<int>("SalesOrderID"),
        SalesOrderDetailID =
            detail.Field<int>("SalesOrderDetailID"),
        OrderDate =
            order.Field<DateTime>("OrderDate"),
        ProductID =
            detail.Field<int>("ProductID")
    };

DataTable orderTable = query.CopyToDataTable();
' Fill the DataSet.
Dim ds As New DataSet()
ds.Locale = CultureInfo.InvariantCulture
' See the FillDataSet method in the Loading Data Into a DataSet topic.
FillDataSet(ds)

Dim orders As DataTable = ds.Tables("SalesOrderHeader")
Dim details As DataTable = ds.Tables("SalesOrderDetail")


Dim query = _
    From order In orders.AsEnumerable() _
    Join detail In details.AsEnumerable() _
    On order.Field(Of Integer)("SalesOrderID") Equals _
            detail.Field(Of Integer)("SalesOrderID") _
    Where order.Field(Of Boolean)("OnlineOrderFlag") = True And _
            order.Field(Of DateTime)("OrderDate").Month = 8 _
    Select New With _
    { _
        .SalesOrderID = order.Field(Of Integer)("SalesOrderID"), _
        .SalesOrderDetailID = detail.Field(Of Integer)("SalesOrderDetailID"), _
        .OrderDate = order.Field(Of DateTime)("OrderDate"), _
        .ProductID = detail.Field(Of Integer)("ProductID") _
    }

Dim table As DataTable = query.CopyToDataTable()

예시

다음 예제에서는 $9.99보다 큰 가격 항목에 대한 컬렉션을 쿼리하고 쿼리 결과에서 테이블을 만듭니다.

// Create a sequence.
var items = new Item[]
{ new Book{Id = 1, Price = 13.50, Genre = "Comedy", Author = "Gustavo Achong"},
  new Book{Id = 2, Price = 8.50, Genre = "Drama", Author = "Jessie Zeng"},
  new Movie{Id = 1, Price = 22.99, Genre = "Comedy", Director = "Marissa Barnes"},
  new Movie{Id = 1, Price = 13.40, Genre = "Action", Director = "Emmanuel Fernandez"}};

// Query for items with price greater than 9.99.
IOrderedEnumerable<Item> query = from i in items
                                 where i.Price > 9.99
                                 orderby i.Price
                                 select i;

// Load the query results into new DataTable.
DataTable table = query.CopyToDataTable();
Dim book1 As New Book()
book1.Id = 1
book1.Price = 13.5
book1.Genre = "Comedy"
book1.Author = "Gustavo Achong"

Dim book2 As New Book
book2.Id = 2
book2.Price = 8.5
book2.Genre = "Drama"
book2.Author = "Jessie Zeng"

Dim movie1 As New Movie
movie1.Id = 1
movie1.Price = 22.99
movie1.Genre = "Comedy"
movie1.Director = "Marissa Barnes"

Dim movie2 As New Movie
movie2.Id = 1
movie2.Price = 13.4
movie2.Genre = "Action"
movie2.Director = "Emmanuel Fernandez"

Dim items(3) As Item
items(0) = book1
items(1) = book2
items(2) = movie1
items(3) = movie2

' Query for items with price greater than 9.99.
Dim query = From i In items _
            Where i.Price > 9.99 _
            Order By i.Price _
            Select New With {i.Price, i.Genre}

Dim table As DataTable
table = query.CopyToDataTable()

예시

다음 예제에서는 9.99보다 큰 가격의 항목에 대한 컬렉션을 쿼리하고 결과를 투영합니다. 익명 형식의 반환된 시퀀스는 기존 테이블에 로드됩니다.

// Create a sequence.
var items = new Item[]
{ new Book{Id = 1, Price = 13.50, Genre = "Comedy", Author = "Gustavo Achong"},
  new Book{Id = 2, Price = 8.50, Genre = "Drama", Author = "Jessie Zeng"},
  new Movie{Id = 1, Price = 22.99, Genre = "Comedy", Director = "Marissa Barnes"},
  new Movie{Id = 1, Price = 13.40, Genre = "Action", Director = "Emmanuel Fernandez"}};

// Create a table with a schema that matches that of the query results.
var table = new DataTable();
table.Columns.Add("Price", typeof(int));
table.Columns.Add("Genre", typeof(string));

var query = from i in items
            where i.Price > 9.99
            orderby i.Price
            select new { i.Price, i.Genre };

query.CopyToDataTable(table, LoadOption.PreserveChanges);
Dim book1 As New Book()
book1.Id = 1
book1.Price = 13.5
book1.Genre = "Comedy"
book1.Author = "Gustavo Achong"

Dim book2 As New Book
book2.Id = 2
book2.Price = 8.5
book2.Genre = "Drama"
book2.Author = "Jessie Zeng"

Dim movie1 As New Movie
movie1.Id = 1
movie1.Price = 22.99
movie1.Genre = "Comedy"
movie1.Director = "Marissa Barnes"

Dim movie2 As New Movie
movie2.Id = 1
movie2.Price = 13.4
movie2.Genre = "Action"
movie2.Director = "Emmanuel Fernandez"

Dim items(3) As Item
items(0) = book1
items(1) = book2
items(2) = movie1
items(3) = movie2

' Create a table with a schema that matches that of the query results.
Dim table As DataTable = New DataTable()
table.Columns.Add("Price", GetType(Integer))
table.Columns.Add("Genre", GetType(String))

' Query for items with price greater than 9.99.
Dim query = From i In items _
            Where i.Price > 9.99 _
            Order By i.Price _
            Select New With {i.Price, i.Genre}

query.CopyToDataTable(table, LoadOption.PreserveChanges)

예시

다음 예제에서는 $9.99보다 큰 가격 항목을 컬렉션에 쿼리하고 결과를 투영합니다. 익명 형식의 반환된 시퀀스는 기존 테이블에 로드됩니다. 테이블 스키마는 BookMovies 형식이 Item 형식에서 파생되었기 때문에 자동으로 확장됩니다.

// Create a sequence.
var items = new Item[]
{ new Book{Id = 1, Price = 13.50, Genre = "Comedy", Author = "Gustavo Achong"},
  new Book{Id = 2, Price = 8.50, Genre = "Drama", Author = "Jessie Zeng"},
  new Movie{Id = 1, Price = 22.99, Genre = "Comedy", Director = "Marissa Barnes"},
  new Movie{Id = 1, Price = 13.40, Genre = "Action", Director = "Emmanuel Fernandez"}};

// Load into an existing DataTable, expand the schema and
// autogenerate a new Id.
var table = new DataTable();
DataColumn dc = table.Columns.Add("NewId", typeof(int));
dc.AutoIncrement = true;
table.Columns.Add("ExtraColumn", typeof(string));

var query = from i in items
            where i.Price > 9.99
            orderby i.Price
            select new { i.Price, i.Genre };

query.CopyToDataTable(table, LoadOption.PreserveChanges);
Dim book1 As New Book()
book1.Id = 1
book1.Price = 13.5
book1.Genre = "Comedy"
book1.Author = "Gustavo Achong"

Dim book2 As New Book
book2.Id = 2
book2.Price = 8.5
book2.Genre = "Drama"
book2.Author = "Jessie Zeng"

Dim movie1 As New Movie
movie1.Id = 1
movie1.Price = 22.99
movie1.Genre = "Comedy"
movie1.Director = "Marissa Barnes"

Dim movie2 As New Movie
movie2.Id = 1
movie2.Price = 13.4
movie2.Genre = "Action"
movie2.Director = "Emmanuel Fernandez"

Dim items(3) As Item
items(0) = book1
items(1) = book2
items(2) = movie1
items(3) = movie2

' Load into an existing DataTable, expand the schema and
' autogenerate a new Id.
Dim table As DataTable = New DataTable()
Dim dc As DataColumn = table.Columns.Add("NewId", GetType(Integer))
dc.AutoIncrement = True
table.Columns.Add("ExtraColumn", GetType(String))

Dim query = From i In items _
            Where i.Price > 9.99 _
            Order By i.Price _
            Select New With {i.Price, i.Genre}

query.CopyToDataTable(table, LoadOption.PreserveChanges)

예시

다음 예제에서는 $9.99보다 큰 가격의 항목에 대한 컬렉션을 쿼리하고 새 테이블에 로드되는 시퀀스를 Double반환합니다.

// Create a sequence.
var items = new Item[]
{ new Book{Id = 1, Price = 13.50, Genre = "Comedy", Author = "Gustavo Achong"},
  new Book{Id = 2, Price = 8.50, Genre = "Drama", Author = "Jessie Zeng"},
  new Movie{Id = 1, Price = 22.99, Genre = "Comedy", Director = "Marissa Barnes"},
  new Movie{Id = 1, Price = 13.40, Genre = "Action", Director = "Emmanuel Fernandez"}};

// load sequence of scalars.
IEnumerable<double> query = from i in items
                            where i.Price > 9.99
                            orderby i.Price
                            select i.Price;

DataTable table = query.CopyToDataTable();
Dim book1 As New Book()
book1.Id = 1
book1.Price = 13.5
book1.Genre = "Comedy"
book1.Author = "Gustavo Achong"

Dim book2 As New Book
book2.Id = 2
book2.Price = 8.5
book2.Genre = "Drama"
book2.Author = "Jessie Zeng"

Dim movie1 As New Movie
movie1.Id = 1
movie1.Price = 22.99
movie1.Genre = "Comedy"
movie1.Director = "Marissa Barnes"

Dim movie2 As New Movie
movie2.Id = 1
movie2.Price = 13.4
movie2.Genre = "Action"
movie2.Director = "Emmanuel Fernandez"

Dim items(3) As Item
items(0) = book1
items(1) = book2
items(2) = movie1
items(3) = movie2

Dim query = From i In items _
            Where i.Price > 9.99 _
            Order By i.Price _
            Select i.Price

Dim table As DataTable
table = query.CopyToDataTable()

참고하십시오