How to assign an alias to the result of a calculation
In the last figure, you saw one way to assign an alias to the result of a calculation. If you look back at the example in that figure, however, you'll see that the same calculation is performed in the where, orderby, and select clauses.To avoid that, you can use the let clause shown in figure 11-8.
As you can see, you can use the let clause to assign an alias to an expression. In the query expression in this figure, the let clause calculates the balance due for each invoice and assigns the alias BalanceDue to the result of that calculation. Then, the where, orderby, and select clauses that follow all refer to this alias.
If you look at the code that executes this query, you'll see that it's identical to the code in figure 11-7. That's possible because both queries return an anonymous type with VendorID, Number, and BalanceDue properties. However, the query expression in this figure is much simpler because the balance due is calculated only once.
The syntax of the let clauselet alias = expression
A LINQ query that assigns the result of a calculation to a variable
A query expression that calculates the balance duevar invoices = from invoice in invoiceList let BalanceDue = invoice.InvoiceTotal - invoice.PaymentTotal - invoice.CreditTotal where BalanceDue > 0 && invoice.DueDate < DateTime.Today.AddDays(15) orderby invoice.VendorID, BalanceDue descending select new { invoice.VendorID, Number = invoice.InvoiceNumber, BalanceDue };
Code that executes the querystring invoiceDisplay = "Vendor ID\tInvoice No.\tBalance Due\n";foreach (var invoice in invoices){ invoiceDisplay += invoice.VendorID + "\t\t" + invoice.Number + "\t"; if (invoice.Number.Length < 8) invoiceDisplay += "\t"; invoiceDisplay += invoice.BalanceDue.ToString("c") + "\n";}MessageBox.Show(invoiceDisplay, "Sorted Vendor Invoices Due");
The resulting dialog box
Description
Figure 11-8 How to assign an alias to the result of a calculation
How to join data from two or more data sources
Figure 11-9 shows how you can include data from two or more data sources in a query. To do that, you use the join clause shown at the top of this figure. To start, this clause declares a range variable and names a data source just like the from clause does. Then, it indicates how the two data sources are related.
To illustrate, the first example in this figure joins data from the list of Invoice objects you've seen in the previous figures with a list of Vendor objects. To do that, it names the invoice list on the from clause, and it names the vendor list on the join clause. Then, the on condition indicates that only vendors in the vendor list with vendor IDs that match vendor IDs in the invoice list should be included in the results.
Because both the invoice and vendor lists are included as data sources in this query expression, the rest of the query can refer to properties of both Invoice and Vendor objects. For example, the where clause in this query expression compares the DueDate property of the Invoice objects to 15 days from the current date. Similarly, the orderby clause sorts the results by the Name property of the Vendor objects. And the select clause selects the Name property from the Vendor objects and the InvoiceNumber property from the Invoice objects. (All three clauses also include the balance due, which is defined by a let clause.)
The remaining code in this example executes the query and displays a list that includes the vendor names, invoice numbers, and balances due. This is similar to the lists you saw in figures 11-6 and 11-8. Because the list in this figure includes the vendor names instead of the vendor IDs, however, it provides more useful information.
Although this figure only shows how to join data from two data sources, you can extend this syntax to join data from additional data sources. For example, suppose you have three data sources named vendorList, invoiceList, and lineItemList. Then, you could join the data in these lists using code like this:
from vendor in vendorListjoin invoice in invoiceListon vendor.vendorID equals invoice.vendorIDjoin lineItem in lineItemListon invoice.invoiceID equals lineItem.invoiceID...
Once the three lists are joined, you can refer to properties from any of these lists in the query expression.
The basic syntax of the join clausejoin elementName in collectionName on keyName1 equals keyName2
A LINQ query that joins data from two data sources
A query expression that joins data from generic lists of invoices and vendorsvar invoices = from invoice in invoiceList join vendor in vendorList on invoice.VendorID equals vendor.VendorID let BalanceDue = invoice.InvoiceTotal - invoice.PaymentTotal - invoice.CreditTotal where BalanceDue > 0 && invoice.DueDate < DateTime.Today.AddDays(15) orderby vendor.Name, BalanceDue descending select new { vendor.Name, Number = invoice.InvoiceNumber, BalanceDue };
Code that executes the querystring invoiceDisplay = "Vendor Name\t\t\tInvoice No.\tBalance Due\n";foreach (var invoice in invoices){ invoiceDisplay += invoice.Name + "\t\t"; if (invoice.Name.Length < 20) invoiceDisplay += "\t"; if (invoice.Name.Length < 10) invoiceDisplay += "\t"; invoiceDisplay += invoice.Number + "\t"; if (invoice.Number.Length < 8) invoiceDisplay += "\t"; invoiceDisplay += invoice.BalanceDue.ToString("c") + "\n";}MessageBox.Show(invoiceDisplay, "Joined Vendor and Invoice Data");
Figure 11-9 How to join data from two or more data sources