1: execution of query statements
A linq query statement is executed immediately without the command line statement. It is just a descriptive statement, for example, in the following statement:
VaR products = dB. Products. Where (P => P. unitprice> 50 );
Foreach (var p in products)
Response. Write (P. productname );
Foreach (var p in products)
Response. Write (P. unitprice );
In the above Code, the actual type of products is iqueryable <product>, and an iqueryable object is like an ADO. net command object, which does not trigger a query execution, but only stores the description of a query. Similarly, an iqueryable only stores a description of the query expression that can be compiled into a database. The executereader () method of a command object will trigger the real execution of the query, the iqueryable object has a getenumerator () method that triggers the execution of the LINQ query statement and returns an ienumerator <product> object. The preceding code is executed twice because of two foreach statements. This behavior is called delayed execution.
However, we usually want to execute the query statement only once, and the result is reused by the following code. A common practice is to use toarray () or tolist () convert the result to an array or set, and then use.
VaR products = dB. Products. Where (P => P. unitprice> 50 );
VaR productlist = products. tolist ();
Foreach (var p in productlist)
Response. Write (P. productname );
Foreach (var p in productlist)
Response. Write (P. unitprice );
The advantage of delayed execution is that you can construct query statements in segments. For example, you can first construct a part of the query statement and construct another part based on the conditions. In the following example, we will first investigate products that have been purchased more than 30 times, and then determine whether the order is by price or by ID based on the conditions!
VaR products = from P in db. Products
Where p. orderdetails. Count> 30
Select P;
VaR orderbystring = request. querystring ["orderby"];
If (orderbystring = "unitprice ")
{
Products = from P in products
Orderby P. unitprice
Select P;
}
Else if (orderbystring = "ID ")
{
Products = from P in products
Orderby P. productid
Select P;
}
Foreach (var p in products)
Response. Write (P. productname + "<br> ");
2: link query
In the previous exercise, we introduced how to contact other entities through relational features in the object class. If an object defines a link, you can use the following syntax to access the object.
// Query the product order with the product ID 15
VaR orders = dB. Products. Single (P => P. productid = 15). orderdetails;
Of course, you can use the following syntax to query attributes that are not defined in the object class:
VaR orders = from P in db. Products
From o in db. orderdetails
Where p. productid = O. productid & P. productid = 15
Select P. orderdetails;
Or
VaR orders = from P in db. Products
Join o in db. orderdetails on p. productid equals O. productid
Where p. productid = 15
Select P. orderdetails;
Using link attributes to define objects makes it easy to use ". "operator, but the main reason for defining object objects in this way is to avoid the coupling between classes and classes by not introducing other classes when using a class,
3: delayed loading and immediate loading
When you query an object, you only want to query the desired part, such as all the products you list, only when the price of a product is greater than 50 can the product be delivered. That is, only the Order details of the product whose price is greater than 50 are returned, rather than the Order details of all products. At this time, we can use the latency loading technology of dlinq.
VaR products = from P in db. Products
Select P;
Foreach (var p in products)
{
If (P. unitprice> 50)
Sentproducts (P. orderdetails );
}
But sometimes you really want to get the relevant data at the same time. For example, in the above example, you can only get the order of the product when you get the product.
VaR products = from P in db. Products
Where p. unitprice> 50
Select P;
Foreach (var p in products)
{
Foreach (VAR o in P. orderdetails)
{
Response. Write (P. productid + ":" + O. orderid );
}
}
The disadvantage of the above example is that the database is frequently queried, which overburdened the database. The best practice is to return the product and its order status at a time. You can use the cross or link dlinq query generation to achieve this, however, a large amount of data is returned. You may need to define a new anonymous object to convert the data, instead of the original product object. In this way, a large amount of redundant data may be returned,
DataShape DS = new DataShape ();
DS. loadwith <product> (P => P. orderdetails );
DB. Shape = Ds;
VaR products = from P in db. Products
Where p. unitprice> 50
Select P;
Foreach (var p in products ){
Foreach (VAR o in P. orderdetails ){
Response. Write (P. productid + ":" + O. orderid );
}
}
The loadwith method of DataShape is to notify the framework to return the order of the product at the same time. At the same time, we can use the associatewith method of DataShape to implement subqueries of links.
Northwind DB = new northwind ("Data Source =. \ sqlexpress; Integrated Security = sspi; initial catalog = northwind ;");
DataShape DS = new DataShape ();
DS. associatewith <product> (P => P. orderdetails. Where (O => O. orderid> 10500 ));
DB. Shape = Ds;
VaR products = from P in db. Products
Where p. unitprice> 50
Select P;
Foreach (var p in products ){
Response. Write (P. productid + "------ <br> ");
Foreach (VAR o in P. orderdetails ){
Response. Write ("productid:" + P. productid + "-- orderid:" + O. orderid + "<br> ");
}
}