Vytvoření datové tabulky z dotazu (LINQ to DataSet)

Datová vazba je běžným použitím objektu DataTable . Metoda CopyToDataTable vezme výsledky dotazu a zkopíruje data do , DataTablekteré lze použít pro datovou vazbu. Po provedení operací s daty se nový DataTable sloučí zpět do zdroje DataTable.

Metoda CopyToDataTable pomocí následujícího procesu vytvoří DataTable z dotazu:

  1. Metoda CopyToDataTable naklonuje DataTable ze zdrojové tabulky ( DataTable objekt, který implementuje IQueryable<T> rozhraní). Zdroj IEnumerable obecně pochází z linQ to DataSet výrazu nebo dotazu metody.

  2. Schéma klonované DataTable je sestaveno ze sloupců prvního výčtu DataRow objektu ve zdrojové tabulce a název naklonované tabulky je název zdrojové tabulky se slovem "query" připojeným k ní.

  3. Pro každý řádek ve zdrojové tabulce se obsah řádku zkopíruje do nového DataRow objektu, který se pak vloží do naklonované tabulky. Vlastnosti RowState a RowError vlastnosti se zachovají v rámci operace kopírování. Vyvolá ArgumentException se, pokud DataRow objekty ve zdroji pocházejí z různých tabulek.

  4. Klonovaný DataTable objekt se vrátí po zkopírování všech DataRow objektů ve vstupní tabulce s možností dotazu. Pokud zdrojová sekvence neobsahuje žádné DataRow objekty, vrátí metoda prázdnou DataTable.

CopyToDataTable Volání metody způsobí spuštění dotazu vázaného na zdrojová tabulka.

Když metoda CopyToDataTable narazí buď na hodnotu null odkaz nebo nullable typ hodnoty v řádku ve zdrojové tabulce, nahradí hodnotu hodnotou Value. Tímto způsobem se hodnoty null zpracovávají správně ve vrácené DataTablehodnotě .

Poznámka: Metoda CopyToDataTable přijímá jako vstup dotaz, který může vracet řádky z více DataTable objektů nebo DataSet objektů. Metoda CopyToDataTable zkopíruje data, ale ne vlastnosti ze zdroje DataTable nebo DataSet objektů do vrácené DataTable. Budete muset explicitně nastavit vlastnosti na vráceném DataTableobjektu , například Locale a TableName.

Následující příklad dotazuje tabulku SalesOrderHeader pro objednávky po 8. srpnu 2001 a používá metodu CopyToDataTableDataTable k vytvoření z tohoto dotazu. Pak DataTable je vázán na BindingSource, který funguje jako proxy pro .DataGridView

// 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

Vytvoření vlastní metody CopyToDataTable<T>

Existující CopyToDataTable metody pracují pouze se IEnumerable<T> zdrojem, kde obecný parametr T je typu DataRow. I když je to užitečné, neumožňuje vytváření tabulek ze posloupnosti skalárních typů, z dotazů, které vracejí anonymní typy, nebo z dotazů, které provádějí spojení tabulek. Příklad implementace dvou vlastních CopyToDataTable metod, které načítají tabulku ze posloupnosti skalárních nebo anonymních typů, naleznete v tématu Postupy: Implementace CopyToDataTable<T> Kde obecný typ T není DataRows.

Příklady v této části používají následující vlastní typy:

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

Příklad

Tento příklad provede spojení přes SalesOrderHeader tabulky a SalesOrderDetail získá online objednávky z měsíce srpna a vytvoří tabulku z dotazu.

// 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()

Příklad

Následující příklad dotazuje kolekci pro položky s cenou vyšší než 9,99 USD a vytvoří tabulku z výsledků dotazu.

// 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()

Příklad

Následující příklad dotazuje kolekci pro položky s cenou vyšší než 9,99 a výsledky projektuje. Vrácená posloupnost anonymních typů se načte do existující tabulky.

// 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)

Příklad

Následující příklad dotazuje kolekci pro položky s cenou vyšší než 9,99 USD a výsledky projektuje. Vrácená posloupnost anonymních typů se načte do existující tabulky. Schéma tabulky se automaticky rozbalí, protože typy Book jsou Movies odvozeny od typu 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)

Příklad

Následující příklad dotazuje kolekci pro položky ceny vyšší než 9,99 USD a vrátí posloupnost Double, která je načtena do nové tabulky.

// 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()

Viz také