Query operators such as SelectMany, Concat, Object Initializers, OrderBy,
AsEnumerable, defaultifempty and how to do left joins in LINQ to SQL.
Standard Query Operators
The list of standard query operators is huge. I will cover a few of them that I found interesting and that require a bit of understanding.
Select Many and Concat Operators
The SelectMany operator is used to create one to many projections. The SelectMany operator will return zero or more inputs for every input element. The prototype is as follows:
public static IEnumerable<s> SelectMany
this IEnumerable
Func
The operator takes an input sequence of T and a selector delegate that takes an element of type T. It returns an IEnumerable of S, an intermediate output sequence. Let's see an example:
public static void SelectManyOperator() { string[] items = { "this", "is", "a", "test" }; IEnumerable foreach (char character in characters) { Console.WriteLine(character); } }
|
public static void ConcatAndSelectManyOperator() { string[] books = { "ASP.NET 2.0 Website Programming: Problem - Design - Solution", "Pro ASP.NET 3.5 in C# 2008, Second Edition", "ASP.NET 2.0 Unleashed", "ASP.NET 3.5 Unleashed " }; IEnumerable IEnumerable books.Take(2), books.Skip(2) }.SelectMany(b => b);
}
|
Using concat or selectmany would yield the same results, but the advantage of selectmany is that it allows you to merge more than two sequences to return a single sequence back.
Object Initializers
There is a C# language feature in the upcoming "Orcas" version known as object initializers. Object initializers basically allow the assignment of multiple properties or fields in a single expression. For example, a common pattern for object creation is:
Customer customer = new Customer();
customer.Name = “Roger”;
customer.Address = “1 Wilco Way”;
In this case, there is no constructor of Customer that takes a name and address; however, there are two properties, Name and Address, that can be set once an instance is created. Object initializers allow the same creation with the following syntax:
Customer customer = new Customer()
{ Name = “Roger”, Address = “1 Wilco Way” };
In our earlier CustomerTuple example, we created the CustomerTuple class by calling its constructor. We can achieve the same result via object initializers:
var locals =
customers
.Where(c => c.ZipCode == 91822)
.Select(c =>
new CustomerTuple { Name = c.Name, Address = c.Address });
Notice that object initializers allow the parentheses of the constructor to be omitted. In addition, both fields and settable properties can be assigned within the body of the object initializer.
We now have a succinct syntax for creating queries in C#. However, we also have an extensible way to add new operators (Distinct, OrderBy, Sum, and so on) through extension methods and a distinct set of language features useful in their own right.
The language design team now had several prototypes to get feedback on. So we organized a usability study with many participants who had experience with both C# and SQL. The feedback was almost universally positive, but it was clear there was something missing. In particular, it was difficult for the developers to apply their knowledge of SQL because the syntax we thought was ideal didn’t map very well to their domain expertise.
No comments:
Post a Comment