Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Syntax to execute code block inside Linq query?

Tags:

c#

linq

Here's some code that (obviously) doesn't compile:

var q = from x in myAnonymousTypeCollection
        select new {
          x.ID,
          CalcField = { 
                        switch(x.SomeField) {
                          case 1:
                            return Math.Sqrt(x.Field1);
                          case 2:
                            return Math.Pow(x.Field2, 2);
                          default:
                            return x.Field3;
                        }
                      }
        };

You get the picture; I'm trying to calculate CalcField in a completely different way, depending on what the value of SomeField is. I can't use a Func<> (or can I?), because the input type is anonymous. So what's the right syntax to get this to work?

like image 964
Shaul Behr Avatar asked May 09 '13 16:05

Shaul Behr


People also ask

Which syntax is used in LINQ?

LINQ comes in two syntactical flavors: The Query and the Method syntax. They can do almost the same, but while the query syntax is almost a new language within C#, the method syntax looks just like regular C# method calls.

What is query syntax and method syntax in LINQ?

Query syntax and method syntax are semantically identical, but many people find query syntax simpler and easier to read. Some queries must be expressed as method calls. For example, you must use a method call to express a query that retrieves the number of elements that match a specified condition.

How LINQ query execute?

LINQ queries are always executed when the query variable is iterated over, not when the query variable is created. This is called deferred execution. You can also force a query to execute immediately, which is useful for caching query results. This is described later in this topic.

In which statement the LINQ query is executed?

The Data Source This fact means it can be queried with LINQ. A query is executed in a foreach statement, and foreach requires IEnumerable or IEnumerable<T>. Types that support IEnumerable<T> or a derived interface such as the generic IQueryable<T> are called queryable types.


2 Answers

First off, I usually prefer the method chain syntax over the query syntax for Linq. With that you can do this easily.

var q = myAnonymousTypeCollection
    .Select(x => 
            {
                object calcField; 

                 switch(x.SomeField) 
                 {
                      case 1:
                        calcField = Math.Sqrt(x.Field1);
                      case 2:
                        calcField =  Math.Pow(x.Field2, 2);
                      default:
                        calcField = x.Field3;

                 return new 
                        {
                            x.ID,
                            CalcField = calcField
                        };
            });

Without using method chains, you need either a method or an Func. Let's assume a Func

//replace these with actual types if you can.
Func<dynamic, dynamic> calculateField = 
    x => 
    {
        switch(x.SomeField) {
            case 1:
                return Math.Sqrt(x.Field1);
            case 2:
                return Math.Pow(x.Field2, 2);
            default:
                return x.Field3;
    }

var q = from x in myAnonymousTypeCollection
        select new { x.Id, CalcField = calculateField(x) };

Note: I didn't write this in an IDE, so please excuse any simple errors.

Here is the MSDN for dynamic. However, I have found that once you need to start passing anonymous types around, it is best to make an actual class.

like image 192
cadrell0 Avatar answered Sep 18 '22 12:09

cadrell0


You could wrap your anonymous function as a (self-executing) Func<> delegate. This assumes you know the return type.

var q = from x in myAnonymousTypeCollection
    select new {
      ID = x.ID,
      CalcField = new Func<double>( () => { 
                    switch(x.SomeField) {
                      case 1:
                        return Math.Sqrt(x.Field1);
                      case 2:
                        return Math.Pow(x.Field2, 2);
                      default:
                        return x.Field3;
                    }
                  } )()
    };
like image 43
McGarnagle Avatar answered Sep 18 '22 12:09

McGarnagle