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);
          }
        }
      }
    }
  }
}

share save 171 16 How To Limit String Field Lengths for LINQ to SQL

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

 Generic Delegates and Lambda Expressions

share save 171 16 Generic Delegates and Lambda Expressions

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

share save 171 16 Call for LINQ Content

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!

share save 171 16 Practical Understanding of Lambda Expressions in LINQ

How to Use IDisposable with LINQ

Objects that implement IDisposable are everywhere. The interface even gets its own language features (C#, VB, F#). However, LINQ throws a few wrenches into things:

  1. LINQ’s query syntax depends on expressions; using blocks are statements.
  2. When querying a sequence of IDisposable objects, there’s no easy way to ensure disposal after each element has been consumed.
  3. Returning deferred queries from within a using statement is often desired, but fails spectacularly.

There are possible work-arounds for each issue…

  1. Put the using statement in a method (named or anonymous) that is called from the query.
  2. Refactor the method to inject the IDisposable dependency, as shown in the first part of Marc’s answer here.

But, as you might have guessed, I would like to propose a better solution. The code is really complex, so bear with me:

public static IEnumerable<T> Use<T>(this T obj) where T : IDisposable
{
    try
    {
        yield return obj;
    }
    finally
    {
        if (obj != null)
            obj.Dispose();
    }
}

That’s it. We’re turning our IDisposable object into a single-element sequence. The trick is that the C# compiler will build an iterator for us that properly handles the finally clause, ensuring that our object will be disposed. It might be helpful to set a breakpoint on the finally clause to get a better idea what’s happening.

So how can this simple method solve all our problems? First up: “using” a FileStream object created in a LINQ query:

var lengths = from path in myFiles
              from fs in File.OpenRead(path).Use()
              select new { path, fs.Length };

Since the result of Use() is a single-element sequence, we can think of from fs in something.Use() as an assignment of that single value, something, to fs. In fact, it’s really quite similar to an F# use binding in that it will automatically clean itself up when it goes out of scope (by its enumerator calling MoveNext()).

Next, disposing elements from a collection. I’ll use the same SharePoint problem that AsSafeEnumerable() solves:

var webs = from notDisposed in site.AllWebs
           from web in notDisposed.Use()
           select web.Title;

I find this syntax rather clumsy compared with AsSafeEnumerable(), but it’s there if you need it.

Finally, let’s defer disposal of a LINQ to SQL DataContext until after the deferred query is executed, as an answer to this Stack Overflow question:

IQueryable<MyType> MyFunc(string myValue)
{
    return from dc in new MyDataContext().Use()
           from row in dc.MyTable
           where row.MyField == myValue
           select row;
}

void UsingFunc()
{
    var result = MyFunc("MyValue").OrderBy(row => row.SortOrder);
    foreach(var row in result)
    {
        //Do something
    }
}

The result of MyFunc now owns its destiny completely. It doesn’t depend on some potentially disposed DataContext – it just creates one that it will dispose when it’s done. There are situations where you would want to share a DataContext rather than create one on demand, but again it’s there if you need it.

I’ve only started using this approach recently, so if you have any problems with it please share.

share save 171 16 How to Use IDisposable with LINQ

How to Share Parameters Between Lambda Expressions

When using Linq to objects, you will quickly feel the need to pass some parameters from a method to another but it’s not so easy because each Linq method is not calling the following one. In a Linq sequence, each method is using the result computed by the previous one. So, local contexts are not visible from one method to another.
The compiler is using two technical different ways to let parameters go out of a method.

As an example, let’s first see how the .SelectMany() method is working.

var values1 = new string[] { “1″, “2″ };
var values2 = new string[] { “A”, “B”, “C” };
var q =
from s1 in values1
from s2 in values2
select s1 + s2;

image thumb 2 How to Share Parameters Between Lambda Expressions

This very little example shows that s1 and s2 are both accessible in the select. It’s nice, but how does this work ?
You must know that the ‘from’ statement of the Linq sugar syntax does not match any existing Linq method. Let’s see how we would have written this using the classical C# syntax.

var values1 = new string[] { “1″, “2″ };
var values2 = new string[] { “A”, “B”, “C” };
var q =
values1.SelectMany(s1 => values2.Select(s2 => s1 + s2));

Let’s focus on the SelectMany parameter:

SelectMany(Func<TSource, IEnumerable<TResult>> selector).

The method must return an IEnumerable<TResult>. In our example, we get it using values2.Select(). We are now touching the interesting point. The parameter of the .Select() is also a lambda “s2 => s1 + s2”. In Linq to object a lamda generates an anonymous method and anonymous methods can access their host scope. Here, s1 is visible inside values2.Select().

So the first solution to share parameters between methods is to nest them

like “.SelectMany(s => s.Select(s2 =>’s is accesible here’ ))”

instead of creating a sequence “source.Skip(‘scope1’).Take(‘scope2’)”

Now what if we would like to share a parameter between two following methods like Skip() and Take() ?

Let’s see how the “let” keyword works.

In the next example, I will start from a list of numbers stored as strings.
I would like to get only numbers greater than 10 and order them by their value but keeping the result as an enumeration of string.

We can write it quickly this way:

var values = new string[] { “12″, “4″, “7″, “18″, “32″ };
var q =
from s in values
where Convert.ToInt32(s) > 10
orderby Convert.ToInt32(s)
select s;

This works fine but we all notice the ugly “Convert.ToInt32(s)” used twice on the same value. Thanks to the “let” keyword we can create a new parameter that will be accessible in all the query.

var values = new string[] { “12″, “4″, “7″, “18″, “32″ };
var q =
from s in values
let i = Convert.ToInt32(s)
where i > 10
orderby i
select s;

We can see that the “let” keyword solves this problem extremely easily. But once again the sugar syntax of Linq is really magic. As we always want to know the secrets of magic tricks, let’s try to get the same result without using the “let” keyword and we will find out what the C# compiler is really doing.

Let’s start by decomposing all the steps using the regular C# syntax.

var step1 = values.Where(s => Convert.ToInt32(s) > 10);
var step2 = step1.OrderBy(s => Convert.ToInt32(s));

I have chosen to decompose this way to show that the only place to share something between the Where() and the OrderBy() is the result.

Now we have to make a new parameter travel across the sequence in addition to the current result. The idea is to create a new type to group the current result and the new value. To achieve this easily we can just use a anonymous type.

//step0: Create an anonymous type grouping the original string and the new value in a single element
//step1, step2: ‘i’ is now accessible as a property of each element
//step3: Get back to an enumeration of string by removing the temporary anonymous element

var step0 = values.Select(s => new { s = s, i = Convert.ToInt32(s) });
var step1 = step0.Where(tmp => tmp.i > 10);
var step2 = step1.OrderBy(tmp => tmp.i);
var step3 = step2.Select(tmp => tmp.s);

We can of course write this in a single Linq query

var q =
from tmp in
(from s in values
select new { S = s, I = Convert.ToInt32(s) })
where tmp.I > 10
orderby tmp.I
select tmp.S;

which is the exact equivalent of what is compiled when using the ‘let’ keyword

var q =
from s in values
let i = Convert.ToInt32(s)
where i > 10
orderby i
select s;

Of course the Linq syntax is extremely short but it’s always nice to know what’s happening behind the scene.

I hope this sample can also help you to solve some other problems when playing with Linq.

share save 171 16 How to Share Parameters Between Lambda Expressions

Solving Issues With LINQ Foreach Variables

Can you guess what the output of the following program is?

using System;
using System.Collections.Generic;

namespace Lambda
{
    class Program
    {
        static void Main(string[] args)
        {
            var strings = new[] {"a", "b", "c"};
            var actions = CreateActions(strings);
            actions.ForEach(f => f());
        }

        private static List CreateActions(IEnumerable strings)
        {
            var actions = new List();

            foreach (var s in strings)
                actions.Add( () => Console.WriteLine(s) );

            return actions;
        }
    }
}

I expected to see all three strings (a, b and c), but instead I got this:
firstoutput Solving Issues With LINQ Foreach Variables

While analyzing the IL code with Reflector I learned a thing or two about lambdas in C#.
When a lambda is encountered by the compiler, it generates a class which has a field for each local variable used by the lambda. In this case, the generated class would look like this in C#:

private sealed class <>c_DisplayClass3
{
    public string s;
    public void 
b_0() { Console.WriteLine(this.s); } }

Of course, the above is not valid C# due to invalid characters in identifiers, but is pretty much what is produced in the IL.
So far so good – no real surprises here. However, look at this code which is my translation from IL to C# of the CreateActions method:

private static List CreateActions(IEnumerable strings)
{
    List actions = new List();
    using (IEnumerator enumerator = strings.GetEnumerator())
    {
        // Note 1: The lambda is created outside of the loop
        <>c_DisplayClass3 lambda = new <>c_DisplayClass3();

        string s;
        while (enumerator.MoveNext())
        {
            s = enumerator.Current;

            // Note 2: The instance field is reassigned each time
            lambda.s = s;
            actions.Add(lambda);
        }
    }
    return actions;
}

The reason for the strange output is clear now – the compiler did not create a lambda object in each iteration but rather reused the existing one each time. After the loop, all items in the actions list are actually the same instance and their s field is the last element of the collection. Apparently, C# compiler creates a lambda instance immediately before the local variable it uses. So, in order to force it to create a new lambda for each iteration, we need to introduce a new local variable in the loop:

private static List CreateActions(IEnumerable strings)
{
    var actions = new List();

    foreach (var s in strings)
    {
        // This variable will be used in the lambda
        var lambda_param = s;
        actions.Add( () => Console.WriteLine(lambda_param) );
    }

    return actions;
}

With this modification the program now produces this output:
secondoutput Solving Issues With LINQ Foreach Variables

share save 171 16 Solving Issues With LINQ Foreach Variables

How to Execute Arbitrary SQL using LINQ to SQL [Video]

This video, courtesy of Microsoft’s ASP.NET video series, provides an example of using LINQ to SQL to execute arbitrary SQL against a database.

share save 171 16 How to Execute Arbitrary SQL using LINQ to SQL [Video]

How to Update a Table with LINQ to SQL and Stored Procedures [Video]

This video, courtesy of Microsoft’s ASP.NET video series, provides an example of using LINQ to SQL and stored procedures to update a table.

share save 171 16 How to Update a Table with LINQ to SQL and Stored Procedures [Video]

How to Use Stored Procedures with LINQ to SQL [Video]

This video, courtesy of Microsoft’s ASP.NET video series, provides an example of using LINQ to SQL with stored procedures.

share save 171 16 How to Use Stored Procedures with LINQ to SQL [Video]
 Page 2 of 10 « 1  2  3  4  5 » ...  Last »