Skapa en datatabell från en fråga (LINQ till DataSet)
Databindning är en vanlig användning av DataTable objekt. Metoden CopyToDataTable tar resultatet av en fråga och kopierar data till en DataTable, som sedan kan användas för databindning. När dataåtgärderna har utförts sammanfogas den nya DataTable tillbaka till källan DataTable.
Metoden CopyToDataTable använder följande process för att skapa en DataTable från en fråga:
Metoden CopyToDataTable klonar en DataTable från källtabellen (ett DataTable objekt som implementerar IQueryable<T> gränssnittet). Källan IEnumerable har vanligtvis sitt ursprung från en LINQ-till DataSet-uttrycks- eller metodfråga.
Schemat för den klonade DataTable skapas från kolumnerna i det första uppräknade DataRow objektet i källtabellen och namnet på den klonade tabellen är namnet på källtabellen med ordet "fråga" som läggs till i den.
För varje rad i källtabellen kopieras innehållet i raden till ett nytt DataRow objekt, som sedan infogas i den klonade tabellen. Egenskaperna RowState och RowError bevaras i kopieringsåtgärden. En ArgumentException utlöses om objekten DataRow i källan kommer från olika tabeller.
Den klonade DataTable returneras när alla DataRow objekt i den frågebara indatatabellen har kopierats. Om källsekvensen inte innehåller några DataRow objekt returnerar metoden en tom DataTable.
CopyToDataTable Om du anropar metoden körs frågan som är bunden till källtabellen.
CopyToDataTable När metoden påträffar antingen en null-referens eller nullbar värdetyp på en rad i källtabellen ersätter den värdet med Value. På så sätt hanteras null-värden korrekt i den returnerade DataTable.
Obs! Metoden CopyToDataTable accepterar som indata en fråga som kan returnera rader från flera DataTable eller DataSet objekt. Metoden CopyToDataTable kopierar data men inte egenskaperna från källan DataTable eller DataSet objekten till den returnerade DataTable. Du måste uttryckligen ange egenskaperna för den returnerade DataTable, till exempel Locale och TableName.
Följande exempel frågar tabellen SalesOrderHeader efter den 8 augusti 2001 och använder metoden för att skapa en DataTable från den CopyToDataTable frågan. DataTable är sedan bunden till en BindingSource, som fungerar som proxy för en 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
Skapa en anpassad CopyToDataTable<T-metod>
De befintliga CopyToDataTable metoderna fungerar bara på en IEnumerable<T> källa där den generiska parametern T
är av typen DataRow. Även om detta är användbart tillåter det inte att tabeller skapas från en sekvens med skalära typer, från frågor som returnerar anonyma typer eller från frågor som utför tabellkopplingar. Ett exempel på hur du implementerar två anpassade CopyToDataTable
metoder som läser in en tabell från en sekvens med skalära eller anonyma typer finns i Så här implementerar du CopyToDataTable<T> där den generiska typen T inte är en DataRow-fil.
Exemplen i det här avsnittet använder följande anpassade typer:
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
Exempel
Det här exemplet utför en koppling över tabellerna SalesOrderHeader
och SalesOrderDetail
för att hämta onlinebeställningar från augusti månad och skapar en tabell från frågan.
// 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()
Exempel
I följande exempel efterfrågas en samling för prisobjekt som är större än 9,99 USD och skapar en tabell från frågeresultatet.
// 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()
Exempel
I följande exempel efterfrågas en samling för prisobjekt som är större än 9,99 och resultatet projiceras. Den returnerade sekvensen av anonyma typer läses in i en befintlig tabell.
// 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)
Exempel
I följande exempel efterfrågas en samling för prisobjekt som är större än 9,99 USD och resultatet projiceras. Den returnerade sekvensen av anonyma typer läses in i en befintlig tabell. Tabellschemat expanderas automatiskt eftersom typerna Book
och Movies
härleds från Item
typen.
// 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)
Exempel
I följande exempel efterfrågas en samling för prisobjekt som är större än 9,99 USD och returnerar en sekvens med Double, som läses in i en ny tabell.
// 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()