LINQ ToLookup vs ToDictionary

Some people are not sure of the difference between ToLookup vs ToDictionary LINQ methods.

To break it down real simple:

  • One is a look up (ToLookup)
  • One is a dictionary (ToDictionary)

Duh – that’s what you’re probably thinking. The real difference is understanding what each of these data structures do.

Lookups

A lookup is a key value pair in which multiple keys of the same value can exist, therefore resulting in a “lookup” type of scenario. The perfect example for this is to assume that we have a List of Author objects. The author object contains the following:

  • First Name
  • Last Name
  • Year their first book was published
  • Social Security Number

Assume that we’d like to give the user the option to select the authors based upon the year they published their first book in a WPF app. We could do that like this:

// Returns a list of Authors
var authors = authorService.FindAll();

// Turn the list into a lookup for later use
var authorLookup = authors.ToLookup(k => k.YearFirstPublished, v => v);

// Further down in the code
// Find all authors who published their first book in 1969
// Returns an enumerable of Authors that match that lookup value
var authorsPublishedInParticularYear = authorLookup[1969];

This will return all authors who published their first book in 1969. We could use this look up later in the application as well to look up other values.

The key thing to note here is that a Lookup can have multiple keys of the same value. MSDN states: A Lookup(Of TKey, TElement) resembles a Dictionary(Of TKey, TValue). The difference is that a Dictionary(Of TKey, TValue) maps keys to single values, whereas a Lookup(Of TKey, TElement) maps keys to collections of values.

Dictionaries

A dictionary is a key value pair in which a key can only exist once within the dictionary. You cannot have two entries with the same key. This is the difference between the Dictionary and Lookup data structures.

Using the same Author object we described above we can find an author by their Social Security Number if we turned the list into a dictionary for fast lookups based upon a unique key (the social security number).

This will return a single Author object who’s social security number matches ‘555-55-5555’.

// Returns a list of Authors
var authors = authorService.FindAll();

// Turn the list into a lookup for later use
var authorDictionary = authors.ToDictionay(k => k.SocialSecurityNumber, v => v);

// Further down in the code
// Finds the author with 555-55-5555 as their Social Security Number
var author = authorDictionary["555-55-5555"];

Conclusion

While dictionaries and lookups seem to be nearly the same data structure, they provide completely different functionality based upon the value the key possesses.

GD Star Rating
loading...
GD Star Rating
loading...
  • Share/Bookmark

Implementing LINQ on the .NET Micro Framework

The .NET Micro Framework, a variant of .NET radically scaled down for embedded systems, does not include the System.Linq namespace and does not provide any LINQ functionality. Because its implementation is based on generics, LINQ requires version 2.0 of the CLR. The Micro Framework on the other hand is restricted to the CLI, a standardized specification of Microsoft’s CLR 1.0.

Fortunately, the other relevant language features such as lambda expressions, extension methods and list comprehension can all be seen as syntactic sugar. Introduced with C# 3.0 – and due to the genius of Anders Hejlsberg – those features can be compiled to IL instructions already implemented by any CLI-compliant virtual machine. And, as Marc Frei and Cuno Pfister prove with the following code, the lack of generics barely affects the undeniable elegance of LINQ.

using System.Collections;using Microsoft.SPOT;

namespace System.Runtime.CompilerServices {  [AttributeUsageAttribute(    AttributeTargets.Assembly    | AttributeTargets.Class    | AttributeTargets.Method)]  sealed class ExtensionAttribute: Attribute {}}

delegate bool Predicate (object o);

sealed class Enumerator: IEnumerator {  IEnumerator e;  Predicate p;

  internal Enumerator (IEnumerator e, Predicate p) {    this.e = e;    this.p = p;  }

  object IEnumerator.Current {    get { return e.Current; }  }

  void IEnumerator.Reset () {    e.Reset();  }

  bool IEnumerator.MoveNext () {    var b = e.MoveNext();    while (b && !p(e.Current)) {      b = e.MoveNext();    }    return b;  }}

sealed class Filter: IEnumerable {  IEnumerable e;  Predicate p;

  internal Filter (IEnumerable e, Predicate p) {    this.e = e;    this.p = p;  }

  IEnumerator IEnumerable.GetEnumerator () {    return new Enumerator(e.GetEnumerator(), p);  }}

static class Program {  static int Count (this IEnumerable e) {    var n = 0;    foreach (var o in e) {      n++;    }    return n;  }

  static IEnumerable Where (this IEnumerable e, Predicate p) {    return new Filter(e, p);  }

  static void Main () {    var a = new int[] {1, 2, 3, 4, 6, 8, 9, 9, 9};    var n = a.Where(v => (int) v % 2 == 0).Count();    var m = (from v in a where (int) v % 2 == 0 select v).Count();    Debug.Print(n + " " + m);  }}
GD Star Rating
loading...
GD Star Rating
loading...
  • Share/Bookmark

How to Use .Except with EqualityComparer

Today we’re going to cover an advanced scenario where we need to compare lists of a class we created. We’ll start with an implementation of EqualityComparer<T> which consists of overriding two methods: Equals and GetHashCode. What was a little tricky about this implementation is this subtle, but critical, comment in the code sample on MSDN (in the Enumerable.Except documentation):

// If Equals() returns true for a pair of objects,
// GetHashCode must return the same value for these objects.

// GetHashCode must return the same value for these objects.

public class WidgetComparer : EqualityComparer<Widget>
{
public override bool Equals(Widget x, Widget y)
{
if (ReferenceEquals(x, y)) return true;

return x.Id == y.Id && x.Name == y.Name && x.Price == y.Price;
}

public override int GetHashCode(Widget obj)
{
if (ReferenceEquals(obj, null)) return 0;

var nameHash = obj.Name == null ? 0 : obj.Name.GetHashCode();
var idHash = obj.Id.GetHashCode();
var priceHash = obj.Price.GetHashCode();

return nameHash ^ idHash ^ priceHash;
}
}

Now that we have our EqualityComparer set up for the Widget class, let’s look at how the Except method uses our implementation.

Test 1 – Two lists with same reference items.

[TestMethod]
public void Except_ListsWithSameReferenceItems_ShouldNotYieldDifferences()
{
var widget1 = new Widget { Id = 1, Name = “Widget1″, Price = 0.99 };
var widget2 = new Widget { Id = 2, Name = “Widget2″, Price = 0.99 };
var list1 = new List<Widget> { widget1, widget2 };
var list2 = new List<Widget> { widget1, widget2 };

var results = list1.Except(list2, new WidgetComparer());

Assert.IsTrue(results.Count() == 0);
}

Note in our implementation (which follows the example from MSDN) we check object.ReferenceEquals in the Equals method. But that check alone will not suffice, the result from GetHashCode is also validated so we must calculate the HashCode uniformly for the object as well.

Test 2 – Two lists with same items (but not same references)

[TestMethod]
public void Except_ListsWithSameItems_ShouldNotYieldDifferences()
{
var list1 = new List<Widget>
{
new Widget { Id = 1, Name = “Widget1″, Price = 0.99 },
new Widget { Id = 2, Name = “Widget2″, Price = 0.99 }
};
var list2 = new List<Widget>
{
new Widget { Id = 1, Name = “Widget1″, Price = 0.99 },
new Widget { Id = 2, Name = “Widget2″, Price = 0.99 }
};

var results = list1.Except(list2, new WidgetComparer());

Assert.IsTrue(results.Count() == 0);
}

In this test we use widgets set up with identical properties for each list. The test will still pass because our EqualityComparer evaluates the widgets using the formula we specified (Id, Name, & Price all match).

Test 3 – Two lists with different items. This one is tricky though, because it List 2 is the one that contains different items.

[TestMethod]
public void Except_List2WithDifferentItems_ShouldNotYieldDifferences()
{
var list1 = new List<Widget> {
new Widget { Id = 1, Name = “Widget1″, Price = 0.99 },
new Widget { Id = 2, Name = “Widget2″, Price = 0.99 }
};
var list2 = new List<Widget>{
new Widget {Id = 1, Name = “Widget1″, Price = 0.99},
new Widget {Id = 2, Name = “Widget2″, Price = 0.99},
new Widget { Id = 3, Name = “Widget3″, Price = 0.99 }
};

var results = list1.Except(list2, new WidgetComparer());

Assert.IsTrue(results.Count() == 0);
}

What gives? When you call Except you are saying “Give me everything that is in list 1, that is not in list 2.” In this case, list 2 has more items than list 1 and all the items from list 1 are in list 2.

Test 4 – Two lists with different items. This time list 1 has more items than list 2.

[TestMethod]
public void Except_List1WithDifferentItems_ShouldYieldDifferences()
{
var list1 = new List<Widget> {
new Widget { Id = 1, Name = “Widget1″, Price = 0.99 },
new Widget { Id = 2, Name = “Widget2″, Price = 0.99 },
new Widget { Id = 3, Name = “Widget3″, Price = 0.99 }
};
var list2 = new List<Widget>{
new Widget {Id = 1, Name = “Widget1″, Price = 0.99},
new Widget {Id = 2, Name = “Widget2″, Price = 0.99}
};

var results = list1.Except(list2, new WidgetComparer());

Assert.IsTrue(results.Count() == 1);
}

As expected, we find that Widget3 does not exist in list 2. Remember, when you call Except, say the mantra: “Give me everything that is in list 1, that is not in list 2.”

If you have any comments or improvements on this simple example of using Except, post away!

GD Star Rating
loading...
GD Star Rating
loading...
  • Share/Bookmark

Use LINQ and Reflection to Find Matching Properties

As a side product of some experiments I wrote simple LINQ query that matches properties of two objects and returns these properties as list. The code I wrote is pretty simple and I packed it for you as method.

C#
public IList GetMatchingProperties(object source, object target)
{
if (source == null)
throw new ArgumentNullException(“source”);
if (target == null)
throw new ArgumentNullException(“target”);

var sourceType = source.GetType();
var sourceProperties = sourceType.GetProperties();
var targetType = target.GetType();
var targetProperties = targetType.GetProperties();

var properties = (from s in sourceProperties
from t in targetProperties
where s.Name == t.Name &&
s.PropertyType == t.PropertyType
select s).ToList();
return properties;
}

VB.NET
Public Function GetMatchingProperties(ByVal source As Object,_
ByVal target As Object) As IList(Of PropertyInfo)

If source Is Nothing Then
Throw New ArgumentNullException(“source”)
End If
If target Is Nothing Then
Throw New ArgumentNullException(“target”)
End If

Dim sourceType = source.GetType()
Dim sourceProperties = sourceType.GetProperties()
Dim targetType = target.GetType()
Dim targetProperties = targetType.GetProperties()

Dim properties = (From s In sourceProperties _
From t In targetProperties _
Where s.Name = t.Name AndAlso s.PropertyType = t.PropertyType _
Select s).ToList()
Return properties
End Function

The method returns only those properties that match by name and type. If both objects have property called Sum and both of them have Sum in different type (let’s say float and decimal) then this property is not returned by this method. Of course, you can extend this method if you like and you can make it much more clever. Simple implementation given here worked for me very well.

GD Star Rating
loading...
GD Star Rating
loading...
  • Share/Bookmark

Guidelines and Best Practices in Optimizing LINQ

Language Integrated Query (LINQ) is a query execution pipeline for use in the managed environment of .NET Framework. In essence, LINQ is Microsoft’s object relational mapper between your business objects and the underlying data sources and provides a simplified framework for accessing relational data in an object-oriented fashion.

Although LINQ is great in the sense that you can query data in your object model seamlessly, there are certain factors that you need to consider to ensure that your application performs to the extent you need it to. This article takes a look at some of the best practices that you can follow for enhancing the performance of LINQ in your applications.

The Best Practices

Here are some of the best practices that you can follow to boost your LINQ query performance.

Object tracking. Turn ObjectTrackingEnabled Property off if not required. If you need only to read data through the data context and don’t need to edit the data, you should turn off ObjectTrackingEnabled property; doing so will turn off the unnecessary identity management of objects and help boost the application’s performance.

Here is an example:

using (TestDataContext dataContext = new TestDataContext())

{

dataContext.ObjectTrackingEnabled = false;

}

Data Contexts

If there are multiple disconnected databases that you’re using in your application, try using multiple data contexts to reduce the identity management and object tracking overhead costs. You should attach only those objects to your data context that have been changed.

Compiled queries. You can use compiled queries to boost your application’s performance. But remember that a compiled query could be costly when used for the first time. So, do ensure you use compiled queries only in situations where you need them that is, when you need a query to be used repeatedly.

Optimistic concurrency. Concurrency handling is a mechanism that enables you to detect and resolve conflicts that arise out of concurrent requests to the same resource at any point in time. Concurrency in ADO.NET is of two types: optimistic and pessimistic. LINQ follows an optimistic concurrency model by default. You should avoid using optimistic concurrency if not needed. To turn off the check for optimistic concurrency, you can use UpdateCheck.Never in the attribute level mapping for your entity classes, as shown below:

[Column(Storage="_FirstName", DbType="NText",

UpdateCheck=UpdateCheck.Never)]

public string FirstName

{

get

{

return this._FirstName;

}

set

{

if ((this._FirstName != value))

{

this.OnFirstNameChanging(value);

this.SendPropertyChanging();

this._FirstName = value;

this.SendPropertyChanged(“FirstName”);

this.OnFirstNameChanged();

}

}

}

Retrieve selective data. You should use Take and Skip methods appropriately when you need to bind paged data to data controls. Here is an example:

private List<Student> GetStudentRecordss(int index, int size)

{

using (TestDataContext dataContext = new TestDataContext())

{

return dataContext.Students

.Take< Student >( size)

.Skip< Student >( index * size)

.ToList< Student>();

}

}

You should also filter down your required data appropriately using DataLoadOptions.AssociateWith so that only the data that is required is returned. Here is an example that shows how you can use DataLoadOptions.AssociateWith to retrieve selective data in LINQ:

using (TestDataContext dataContext = new TestDataContext())

{

DataLoadOptions dataLoadOptions = new DataLoadOptions();

dataLoadOptions.AssociateWith<Employee>(emp=> emp.Department.Where<Department>(dept => dept.DeptCode == 1));

dataContext.LoadOptions = dataLoadOptions;

}

Analyze queries. You can also analyze how your LINQ queries have generated the corresponding SQL statements and monitor them in the Visual Studio IDE. To do this, you need to use the Log property of the data context as shown in the code snippet below:

using (TestDataContext dataContext = new TestDataContext())

{

#if DEBUG

dataContext.Log = Console.Out;

#endif

}

 

[SQL Server Magazine]

GD Star Rating
loading...
GD Star Rating
loading...
  • Share/Bookmark

Why You Need to Know LINQ to XML

In .NET 3.5, the primary device for general processing of XML is LINQ To XML. This provides a lightweight, LINQ-friendly DOM along with a set of query operators.

In SiIlverlight, this is your only choice – XmlDocument and related classes are not supported. Even without its LINQ support, the LINQ To XML DOM is valuable as an easy – to – use facade over the XmlReader / Writer classes.

All of the LINQ To XML types are defined in the System.Xml.Linq namespace.

The LINQ To XML DOM, or “X-DOM” consists of types like XDocument, XElement, and XAttribute. All of the methods are “LINQ – friendly” in that they emit IEnumerable sequences on which you can query. The constructors are designed so that you can build an X-DOM tree through a LINQ projection.

For example, this LINQ To SQL query projects directly into an X-DOM:

XElement xml = new XElement(“contacts”,
from c in db.Contacts
orderby c.ContactId
select new XElement(“contact”,
new XAttribute(“contactId”, c.ContactId),
new XElement(“firstName”, c.FirstName),
new XElement(“lastName”, c.LastName))
);

XElement is the most frequently used class. XDocument represents the root of an XML tree; it wraps the root XElement with an XDeclaration, processing instructions,and other root-level items. However, its use is optional – you can load, manipulate and save an X-DOM without creating an XDocument.

XElement and XDocument offer static Load and Parse methods. Load builds an X-DOM through a file, URL, TextReader, or an XmlReader. Parse builds an X-DOM from a string.

Examples:

XDocument fromRss = XDocument.Load( “http://www.eggheadcafe.com/rss.xml”);
(In SIlverlight, this method only works with relative urls)

XElement fromSettings = XElement..Load(“C:\MyProject\web.config”);

XElement person = XElement.Parse( @”<Person>
<FirstName>John</FirstName>
<LastName>Rogers</LastName>
</Person>”);

XNode provides a static ReadFrom method that can instantiate and populate any type of node from an XmlReader. It stops after reading one complete node so you can continue to read nodes manually from the XmlReader.

You can also use an XmlReader or XmlWriter to read and write an XNode via its CreateReader and CreateWriter methods.

If you call ToString on any Node, this converts its content to an XML string formatted with line breaks and indentation.

XElement and XDocument also have a Save method that writes an X-DOM to a file, TextWriter or XmlWriter. WIth a file, the declaration is written automatically. There is also a WriteTo method in XNode that accepts an XmlWriter.

Here is an example of how one might use a LINQ To XML query to populate a Silverlight ListBox containing a StackPanel, directly from a consumed RSS feed:

namespace RSS
{
public class RssItem
{
public string Title { get; set; }
public string Description { get; set; }
public string Link { get; set; }
public string PubDate { get; set;}
}
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
WebClient wc = new WebClient();
wc.DownloadStringCompleted += new DownloadStringCompletedEventHandler(wc_DownloadStringCompleted);
wc.DownloadStringAsync(new Uri(“http://www.eggheadcafe.com/rss.xml”));
}

void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
XElement rss= XElement.Parse(e.Result);
var items = from item in rss.Descendants(“item”)
select new RssItem()
{
Title = item.Element( “title”).Value,
Description = item.Element(“description”).Value,
Link =item.Element(“link”).Value,
PubDate = item.Element(“pubDate”).Value
};
FeedList.ItemsSource = items.ToList();
}
}
}

And the XAML:

<UserControl xmlns:data=”clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data” x:Class=”RSS.MainPage”
xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”
xmlns:d=”http://schemas.microsoft.com/expression/blend/2008″ xmlns:mc=”http://schemas.openxmlformats.org/markup-compatibility/2006″
mc:Ignorable=”d” d:DesignWidth=”640″ d:DesignHeight=”480″>
<Grid x:Name=”LayoutRoot” Width=”400″ Height=”400″>
<ListBox x:Name=”FeedList” Width=”400″ Height=”400″ Visibility=”Visible”>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel x:Name=”Stack1″ Orientation=”Vertical” Visibility=”Visible”>
<HyperlinkButton Width=”400″ Height=”24″ FontFamily=”Arial” NavigateUri=”{Binding Link}” Content=”{Binding Title}” />
<TextBlock Width=”400″ Height=”24″ FontFamily=”Arial” FontWeight=”Bold” Foreground=”Black” Text=”{Binding Description}” TextWrapping=”Wrap” />
<TextBlock Width=”400″ Height=”24″ FontFamily=”Arial” Text=”{Binding PubDate}” />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</UserControl>

Interestingly, the above example will not work with anonymous types (e.g. select new { Title =…. ). You need to define a nominal container class (RssItem, above) in order for databinding to Silverlight controls to work.

Various LINQ operators can be combined and chained to provide specific filtering similar to the WHERE, ORDER BY, AND JOIN clauses (among others) in a SQL query, giving the developer great flexibility once these techniques are mastered.

Navigation is accomplished through a set of Properties on the XNode object, such as Parent, AncestorXXX, and others. Intellisense will provide a rich list of choices to choose from and experiment with; all you need to do is type a “.” dot after an XElement / XNode variable to see the list.

GD Star Rating
loading...
GD Star Rating
loading...
  • Share/Bookmark

How To Limit String Field Lengths for LINQ to SQL

We recently had an issue where a string value in our LINQ object was changed
and became longer than the database field it represented. Whenever we tried
to apply the changes to the database we would get an error. Now, I know that
the correct solution is to implement the proper checks earlier on in the change
cycle but it just erks me a little that the LINQ object doesn’t say:
“Hey, you, coder – you can’t set a value that long to this property because it’s
too long”, when it clearly know what it is.

If you look at the definition of one of the Columns you will see that it has an
Attribute of type ColumnAttribute. This attribute stores all the information
required to map the field back to the database.

[Column(Storage="_AColumn", DbType="VarChar(50) NOT NULL", CanBeNull=false)]
public string AColumn
{
  get

  {
    return this._AColumn;

  }

  set

  {
    if ((this._AColumn != value))

    {
      this.OnNameChanging(value);
      this.SendPropertyChanging();
      this._AColumn = value;
      this.SendPropertyChanged(“AColumn”);
      this.OnNameChanged();
    }
  }
}

We can clearly see from this that our LINQ object does know the column
length so i decide to write a routine to trim off the excess fat. The
routine, when we SubmitChanges during OnValidate, uses reflection to get
the field length and trim the value to fit. Now this could also easily
be used to notify you of fields that are too long as well.

To do this we have to extend our LINQ Data Context. The actual DataContext’s
name is MyDataContext. So we will name the extended one MyDataContext2…
creative huh? We then enumerate through the class’ Properties and then each
Properties Column attributes.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Web;
using System.Reflection;
using System.Data.Linq.Mapping;

public class MyDataContext2 : MyDataContextDataContext
{
  public MyDataContext2 ()
  : base(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString)

  {
  }
}

  public partial class MyTable
  {
    partial void OnValidate(System.Data.Linq.ChangeAction action)
    {
      //Trim all the string fields so that we don’t get DB errors.

      //Check each property in the table
      foreach (MemberInfo memInfo in (typeof(MyTable)).GetProperties())
      {
        //Only Loop through Column attributes
        foreach (object attribute in memInfo.GetCustomAttributes(typeof(ColumnAttribute), true))
        {
          ColumnAttribute ca = (ColumnAttribute)attribute;
          PropertyInfo propInfo = (PropertyInfo)memInfo;

          //Only limit varchar values
          if (ca.DbType.ToLower().Contains(“varchar”))
          {
            string dbType = ca.DbType.ToLower();
            string varchar = “varchar(“;
            int noStart = dbType.ToLower().IndexOf(varchar) + varchar.Length;
            int noEnd = dbType.IndexOf(“)”, noStart);

            string sLength = dbType.Substring(noStart, noEnd – noStart); //strings are stored as VarChar(XXX) NOT NULL

            int iLength = 0;
            int.TryParse(sLength, out iLength);

            string value = string.Empty;

            if (propInfo.GetValue(this, null) != null)
              value = propInfo.GetValue(this, null).ToString();

            if (value.Length > iLength)
              propInfo.SetValue(this, value.Substring(0, iLength), null);
          }
        }
      }
    }
  }
}

GD Star Rating
loading...
GD Star Rating
loading...
  • Share/Bookmark

Generic Delegates and Lambda Expressions

Generic delegates and lambda expressions underpin LINQ. If you’ve been struggling to get your arms around these new concepts, this post should help demystify matters for you.

Of course, there are a a host of other new .NET language features that enable LINQ as well. These include extension methods, type inference, anonymous types, object initializers, and custom iterators, just to name a few! In this post, I’ll address generic delegates and lambda expressions as they pertain to LINQ (that is, as they pertain to the extension methods provided in .NET 3.5 to support LINQ), and I’ll cover some of the other new language features in future posts.

LINQ Query Syntax

There is simply no LINQ without generic delegates and lambda expressions, yet it would seem at first that you can write simple LINQ queries without seeing or touching either a generic delegate or a lambda expression. Here’s a simple example that queries from a collection of customers in custs. In the where clause, we use a boolean allCustomers variable to control whether all customers or only USA customers will be returned.

var allCustomers = false;

var q =
from c in custs
where c.Country == “USA” || allCustomers == true
orderby c.FirstName
select c;

Where’s the generic delegate and the lambda expression in this LINQ query? Oh they’re there all right, but the LINQ query syntax hides those details from the code.

LINQ Method Call Syntax

In reality, the compiler (C# in this case, but VB .NET as well) is supporting a sugar-coated syntax that is strikingly similar to an ordinary SQL query in the RDBMS world, but which really amounts to a chained set of method calls.

What this means is that there is really no such thing as a where clause in LINQ–it’s a Where extension method call.

And guess what? There’s no such thing as an orderby clause either–it’s an OrderBy extension method call, chained to the end of the Where method call.

Meaning that the previous query is treated by the compiler exactly as if you had coded it using LINQ method call syntax as follows:

var q = custs
.Where(c => c.Country == “USA” || allCustomers == true)
.OrderBy(c => c.FirstName);

So this code looks more “conventional,” eh? We’re invoking the Where method on the collection of customers, and then invoking the OrderBy method on the result returned by Where, and obtaining our final filtered and sorted results in q.

LINQ query syntax is obviously cleaner than LINQ method call syntax, but it’s important to understand that only LINQ method call syntax fully implements the complete set of LINQ Standard Query Operators (SQOs), so that you will sometimes be forced to use method call syntax. Also realize that it’s common and normal to use combinations of the two in a single query (I’ll show examples of this using .Concat and other methods in future posts).

Two questions arise at this point:

1) How did the customer collection, which is a List<Customer> in our example, get a Where and OrderBy method?

2) What is the => operator in the method parameters, and what does it do (and how the heck do you pronounce it)?

The answer to the first question is simple: Extension methods. I’ll cover those in more detail in a future post, but for now just understand that the .NET framework 3.5 “extends” any class that implements IEnumerable<T> (virtually any collection, such as our List<Customer>) with the Where and OrderBy methods, as well as many other methods that enable LINQ.

Generic Delegates

The second question is much juicier. First, the => is the lambda operator, and many people verbalize it as ‘goes to’. So ‘c => …’ is read aloud as ‘c goes to…’

To understand lambdas, you need to understand generic delegates and anonymous methods. And to best understand those is to review delegates and generics themselves. If you’ve been programming .NET for any length of time, you’re certain to have encountered delegates. And as of .NET 2.0 (VS 2005), generics have been an important language feature for OOP as well.

A delegate is a data type that defines the “shape” (signature) of a method call. Once you have defined a delegate, you can declare a variable as that delegate. At runtime, the variable can then be pointed to (and then invoke) any available method that matches the signature defined by the delegate. EventHandler is a typical example of a delegate defined by the .NET framework. Here is how .NET defines the EventHandler delegate:

public delegate void EventHandler(object sender, EventArgs e);

This delegate is suitable for pointing to any method that returns no value (void), and accepts two parameters (object sender and EventArgs e); in other words, a typical event handler that has no special event arguments to be passed.

A generic delegate is nothing more than an ordinary delegate, but supports generic type declarations for achieving strongly-typed definitions of the delegate at compile time. This is the same way generics are used for classes. For example, just as the framework provides a List<T> class so that you can have a List of anything, it now also provides a small set of generic delegates named Func that can be used to stongly type many different method signatures; essentially, any method that takes from zero to 4 parameters of any type (T1 through T4) and returns an object of any type (TResult):

public delegate TResult Func<TResult>();
public delegate TResult Func<T, TResult>(T arg);
public delegate TResult Func<T1, T2, TResult>(T1 arg1, T2 arg2);
public delegate TResult Func<T1, T2, T3, TResult>(T1 arg1, T2 arg2, T3 arg3);
public delegate TResult Func<T1, T2, T3, T4, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);

Delegates as Parameters

With these generic Func delegates baked into the .NET framework, LINQ queries can use them as parameters to extension methods such as Where and OrderBy. Let’s examine one overload of the Where extension method:

public static IEnumerable<TSource> Where<TSource>(
this IEnumerable<TSource> source,
Func<TSource, bool> predicate);

What does this mean? Let’s break it down. And to better suit our particular example and simplify the explanation, let’s substitute Customer for TSource:

1) It’s a method called Where<Customer>.

2) It returns an IEnumerable<Customer> sequence.

3) It’s an extension method available to operate on any IEnumerable<Customer>instance (as denoted by the special this keyword in the signature), such as the List<Customer> in our example. The this keyword used in this context means that an extension method for the type following the this keyword is being defined, rather than definining what looks like the first parameter to the method.

4) It takes a single predicate parameter of type Func<Customer, bool>.

Number 4 is key. Func<Customer, bool> is the second Func generic delegate shown above, Func<T, TResult>, where T is Customer and TResult is bool (Boolean). The Func<Customer, bool> delegate refers to any method that accepts a Customer object and returns a bool result. This means that the Where<Customer> method takes a delegate (function pointer) that points to another method which actually implements the filtering logic. This other method will receive each Customer object as the LINQ query iterates the source sequence List<Customer>, apply the desired filtering criteria on it, and return a true or false result in the bool return value that controls whether this particular Customer object should be selected by the query.

How does all that get expressed simply with: .Where(c => c.Country == “USA” || allCustomers == true)?

The best way to answer that question is to first demonstrate two other ways of invoking the Where method. The first is to explicitly provide a delegate instance of Func<Customer, bool> that points to another method called IsCustomerCountryUSA:

private void MainMethod()
{
var filterMethod = new Func<Customer, bool>(IsCustomerCountryUSA);
var q = custs.Where(filterMethod);
}

private bool IsCustomerCountryUSA(Customer c)
{
return (c.Country == “USA”);
}

The Where method takes a single parameter, which is a new instance of the Func<TSource, T> generic delegate that points to a method named IsCustomerCountryUSA. This works because IsCustomerCountryUSA accepts a Customer object and returns a bool result, which is the signature defined by Func<Customer, bool> expected as a parameter by Where<Customer>. Inside the IsCustomerCountryUSA, filtering logic is applied. Note that because we have created IsCustomerCountryUSA as a completely separate method, it cannot access the allCustomers variable defined locally in the calling method (the variable that controls whether all or only USA customers should be selected, as shown at the beginning of this post). Furthermore, because the signature of the IsCustomerCountryUSA method is fixed as determined by Func<Customer, bool>, we can’t just pass the allCustomers variable along as another parameter either. Thus, this approach would require you to define the allCustomers variable as a private member if you wanted to include it in the filtering logic of the IsCustomerCountryUSA method.

Anonymous Methods

Anonymous methods were introduced at the same time as generics in .NET 2.0 (VS 2005). They are useful in cases such as this, where the method we’re creating for the delegate only needs to be called from one place, so the entire method body is simply coded in-line. Since it’s coded in-line at the one and only place it’s invoked, the method doesn’t need to be given a name, hence the term anonymous method.

To refactor the delegate instance version of the code to use an anonymous method, replace the Func parameter passed to the Where method with the actual method signature and body as follows:

var q = custs.Where(delegate(Customer c) { return c.Country == “USA” || allCustomers == true; });

The keyword delegate indicates you’re pointing the delegate parameter Func<Customer, bool> expected by the Where method to an anonymous method. The anonymous method isn’t named, as mentioned, but it must match the Func<Customer, bool> signature, meaning it must accept a Customer object parameter and return a bool result. The explicit signature following the delegate keyword defines the expected single Customer object parameter, and the expected bool result is inferred from the fact that the method returns an expression that resolves to a bool value. If the anonymous method used any other signature or returned anything other than a bool result, the compiler would fail to build your code because the Where<Customer> method is defined to accept only a Func<Customer, bool> delegate.

So now the method body containing the filtering logic that was formerly coded in the separate IsCustomerCountryUSA method appears in braces right after the anonymous method signature. But there’s another huge advantage here besides saving the overhead of declaring a separate method for the filtering logic. Because anonymous methods appear inside of the method that calls them, they magically gain access to the local variables of the calling method. Thus, this implementation can also test the allCustomers variable, even though it’s defined in the calling method which would normally be inaccessible to the method being called. Because of this feature, the allCustomers variable defined as a local variable in the calling method can be tested by the anonymous method as part of the filtering criteria. That means it’s not necessary to define private fields to share local variables defined in a method with an anonymous method that the method calls, as demonstrated here). The result is less code, and cleaner code (though you should be aware that the compiler pulls some fancy tricks to make this possible, and there is a degree of additional runtime overhead involved when accessing local variables of the calling method from the anonymous method being called).

Lambda Expressions

Lambdas were introduced in .NET 3.5 (VS 2008) as a more elegant way of implementing anonymous methods, particularly with LINQ. When a lambda is used to represent an anonymous method containing a single expression which returns a single result, that anonymous method is called a lambda expression. Let’s first refactor our query by converting it from an anonymous method to a lambda:

var q = custs.Where((Customer c) => { return c.Country == “USA” || allCustomers == true; });

All we did was drop the delegate keyword and add the => (“goes to”) operator. The rest looks and works the same as before.

This lambda consists of a single expression that returns a single result, which qualifies it to be refactored as a lambda expression like this:

var q = custs.Where(c => c.Country == “USA” || allCustomers == true);

This final version again works exactly the same way, but has become very terse. First, the Customer data type in the signature isn’t needed, since it’s inferred as the TSource in Func<TSource, bool>. The parentheses surrounding the signature are also not needed, so they’re dropped too. Secondly, since lambda expressions by definition consist of only a single statement, the opening and closing braces for the method body aren’t needed and also get dropped. Finally, since lambda expressions by definition return a single result, the return keyword isn’t needed and is also dropped.

Besides offering an even terser syntax, lambda expressions provide two important additional benefits over anonymous methods. First, as just demonstrated, the data type of the parameter in the signature needn’t be specified since it’s inferred automatically by the compiler. That means that anonymous types (such as those often created by projections defined in the select clause of a LINQ query) can also be passed to lambda expressions. Anonymous types cannot be passed to any other type of method, so this capability was absolutely required to support anonymous types with LINQ. Second, lambda expressions can be used to build expression trees at runtime, which essentially means that your query code gets converted into query data which can then be processed by a particular LINQ implementation at runtime. For example, LINQ to SQL builds an expression tree from the lambda expressions in your query, and generates the appropriate T-SQL for querying SQL Server from the expression tree. Future posts will cover anonymous types and expression trees in greater detail.

To Sum It All Up

So this final lambda expression version invokes the Where method on the List<Customer> collection in custs. Because List<Customer> implements IEnumerable<T>, the Where extension method which is defined for any IEnumerable<T> is available to be invoked on it. The Where<Customer> method expects a single parameter of the generic delegate type Func<Customer, bool>. Such a parameter can be satisfied by the in-line lambda expression shown above, which accepts a Customer object as c =>, and returns a bool result by applying a filtering condition on the customer’s Country property and the calling method’s allCustomers variable.

And as expained at the beginning of this post, the method syntax query using our final lambda expression is exactly what the compiler would generate for us if we expressed it using this query syntax:

var q =
from c in custs
where c.Country == “USA” || allCustomers == true
select c;

I hope this helps clear up any confusion there is surrounding lambda expressions in .NET 3.5.

Happy coding!

 

This article was submitted by Lenni Lobel on .NET and SQL Server Development

Lenni Lobel

GD Star Rating
loading...
GD Star Rating
loading...
  • Share/Bookmark

Call for LINQ Content

As part of our goal to make Linq Exchange a more social website, I’m inviting you, the friendly reader, to submit your LINQ or Lambda Expression article. Your article will appear on the Linq Exchange website within one week of submission (pending review and approval).

You may include one link back to your blog or website (including graphic logo).

Submission Rules:

  1. Your article must be about LINQ or Lambda Expressions
  2. Your article must be at least 350 words in length
  3. You must include at least one code example
  4. You may provide one link and graphic logo to your website or blog. This link will be placed at the end of your article.
  5. You may submit your article as a PDF, Word doc, HTML file, or plain text (HTML is preferred, please).
  6. Your article will appear on the Linq Exchange website withing seven days of submission, pending review and approval by the Linq Exchange team.

 

Submit your articles to articles@linqexchange.com

GD Star Rating
loading...
GD Star Rating
loading...
  • Share/Bookmark

Practical Understanding of Lambda Expressions in LINQ

Lambda expressions are a powerful tool to writing quick, concise code. They can be used in numerous situations, most notably in conjuction with LINQ statements.

A lambda expression is an anonymous function that can contain expressions and statements, and can be used to create delegates or expression tree types.

All lambda expressions use the lambda operator =>, which is read as “goes to”. The left side of the lambda operator specifies the input parameters (if any) and the right side holds the expression or statement block. The lambda expression x => y * z is read “x goes to y times z.”

Here’s how a typical LINQ query looks like without using lambda expressions:

var query = from m in db.PersonalMessages
where m.ConversationID_FK == ConversationID
select m;

Okay, not bad. It looks like a SQL query in reverse (i.e. you start off with “from” and end with “select”). This is so that intellisense can help you out—if you started with select, it would have on idea where you were going with the query.

we are selecting PersonalMessages where the ConversationID is equal to some value passed into the method. The query itself is kinda verbose, and I like to keep my code short and sweet, so how do I re-write this using lambda expressions? Here is the code, and then we’ll break it down:

var query = db.PersonalMessages
.Where(m => m.ConversationID_FK == ConversationID);

We got rid of “select’”, “from” and “in”, etc. Cleaned it up quite a bit. What all is happening though? Basically it’s written out like:

My Query = Get Personal Messages from my data context Where the ConversationID is equal to this #

In other words, it reads exactly like it does in the first written out query, but it’s done faster. The where statement is like a mini-method. You’re defining some variable M (you can use any letter, I always use m for the sake of convention in my code) and then in this case you’re giving m some condition to work with.

You’re basically saying, define m real quick (m=>) as a stand-in for PersonalMessage. Then only return PersonalMessages where m’s ConversationID is equal to some value. Again, just to drill in the point, it’s like typing in:

var query = DataContext.PersonalMessages.Where(PersonalMessage=>PresonalMessage.ConvoID = ConvoID);

Now I want to get even faster with my method calling. Instead of defining a query, then returning it, or doing other things to it, I can easily chain things to it. Lets say I want to return a List of personal messages. I can now do:

List<PersonalMessage> myPersonalMessages = db.PersonalMessages
.Where(m => m.ConversationID_FK == ConversationID)
.ToList();

Very easy. I can go even further, now, all with the ease of dot notation. Lets say I want to order it by the date the personal message was created. No problem, I can throw in an .OrderBy:

List<PersonalMessage> myPersonalMessages = db.PersonalMessages
.Where(m => m.ConversationID_FK == ConversationID)
.OrderBy(m=>m.DateCreated)
.ToList();

Again, I’m creating a little “mini-method” that is passing in the personal message as m, and saying to order it by the date it was created. The possibilities are limitless!

GD Star Rating
loading...
GD Star Rating
loading...
  • Share/Bookmark
 Page 1 of 10  1  2  3  4  5 » ...  Last »