F# “fun” with Windows Phone 7

 

Don syme announced the availability of F# for Windows Phone 7 (link). Daniel Mohl has a project template for F# apps that Don showed in the F# community demo (link).

Note: Anyone wanting to start off a project from scratch can download the project template that I created from here. This is a simple F# WP7 app template without the extra demo files.

As with my previous posts (long back, can’t find enough time these days), I ported the Stock ticker code base to WP7. The UI is pretty simple, It only has a ListBox to show the stock data. The ListBox has a custom ItemTemplate that defines the layout for the input data pulled over the web (Yahoo finance). The application also checks for network connectivity. Below is a snapshot,

image

This sample only pulls the stocks when you click the button, Since it is used in a phone, actual CEP kind of scenario would not be suitable, so keeping the updates in deferred mode. UI polishing + added features would make this a good app for the market store, what do you think? ;)

Sample with source code link.

-Fahad

CEP Client – Remix (WPF & SL)

My previous post had implementation of Rx + F# + Syncfusion WPF GridDataControl. This post is a continuation with a cleaner sample + a Silverlight 4 client using the same abstractions. The technologies used are,

· Rx (http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx), Download the latest version for Silverlight.

· F# – (http://www.silverlight.net/getstarted/silverlight-4/) Get the latest SL4 tools for VS2010, it includes a copy of Fsharp.Core.dll built for the SL 4 Framework.

The sample code is much the same; it uses code sharing between the WPF / SL source projects with some conditional compilation constants to make it build properly. One more caveat is that, since we doing a Webrequest call over the network, we need elevated permissions to do in a Silverlight application, without this we would have to host a client access policy file in the server. Only way is to run the SL application in an elevated trust.

Silverlight 4 – Out Of Browser application,

image

You would have to send me an email again to get the sample code. May be if I get more time, I can work on this and make it colorful to host it in our site itself :) .

-Fahad

‘case like classes’ in C# 4.0

 

“case classes” are a notion in scala. It provides an easier syntax to quickly create POJO objects (Its POCO – Plain Old CLR Objects, in .NET). When I first looked at this couple of days back, I was sure this could done with C# too. Here is what I checked,

  • Use dynamic keyword from C# 4.0
  • Create a simple key/value pair to define the property bag values.
  • Construct a dynamic object based on these values.

This looks pretty straight forward. The code is very simple, the CaseClass <- (dervies from) DynamicObject, and keeps a simple key/value pair mapping.

public class CaseClass : DynamicObject
    {
        private Dictionary<string, object> members;
        public CaseClass(IDictionary<string, object> propertyValues)
        {
            this.members = new Dictionary<string, object>();
            foreach (var kvp in propertyValues)
            {
                if (!this.members.ContainsKey(kvp.Key))
                {
                    this.members.Add(kvp.Key, kvp.Value);
                }
            }
        }

        public CaseClass Extends(CaseClass parent)
        {
            var instance = new CaseClass(this.members);
            foreach (var kvp in parent.members)
            {
                if (!instance.members.ContainsKey(kvp.Key))
                {
                    instance.members.Add(kvp.Key, kvp.Value);
                }
                else
                {
                    throw new InvalidOperationException("child object contains the same property key " + kvp.Key);
                }
            }

            return instance;
        }

        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            if (this.members.ContainsKey(binder.Name))
            {
                result = this.members[binder.Name];
                return true;
            }
            else
            {
                return base.TryGetMember(binder, out result);
            }
        }

        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            if (!this.members.ContainsKey(binder.Name))
            {
                this.members.Add(binder.Name, value);
            }
            else
            {
                this.members[binder.Name] = value;
            }
            return true;
        }

        public override IEnumerable<string> GetDynamicMemberNames()
        {
            return this.members.Keys;
        }
    }

Couple of interesting things,
  • It uses the fluent API interface.
  • If you want to extend a class object, simply call the Extends method and pass the parent class to it.

Usage of it is pretty simple too,

class Program
   {
       static void Main(string[] args)
       {
           var dict = new Dictionary<string, object>() { { "Name", "Fahad" }, { "Age", 25 } };
           var personalInfo = new CaseClass(dict);
           dynamic d1 = personalInfo;
           Console.WriteLine(d1.Name);
           Console.WriteLine(d1.Age);

           var work = new CaseClass(new Dictionary<string, object>() { { "Profession", "Software Engineer" } });           
           dynamic d2 = work.Extends(personalInfo);
           Console.WriteLine(d2.Profession);

           Console.ReadKey(true);
       }
   }

This shows the power of C#, (of course you don’t get intelli-sense / static typed values), but then its only for specific use cases, not everyone has to deal being dynamic. There are couple of more features that the Scala case classes provide, the ToString() / GetHashCode() / Equals() overrides that the scala compiler does for you. Anybody interested can simply add some more functionality in the above code.

Disclaimer: This post is just to show the usage of C# in one way as in Scala, It doesn’t completely replicate the functionality that is provided as-is in Scala.

-Fahad

CEP client with WPF Grid Data Control

CEP Client with WPF GridDataControl

Microsoft StreamInsight CEP platform is very powerful to develop Complex Event Processing (CEP) systems. There are several development models that we can follow. In this post we will use the IObservable / IObserver model using .NET Reactive extensions (Rx). Since this would be a real-time application, we would also be using F# async workflows to pull stock data.

image

F# async workflows are the coolest part of using F# in a real-time application. It allows writing concise code that

· Executes in parallel

· Expose to another .NET library with ease

I won’t go in detail about F# except for the async workflow used in this application. There is a three part series on using design patterns for F# async workflows, I have used the Pattern #3 in this post, since we are using Rx to invoke the workflows. In this design pattern, the worker reports the progress through events, modified version of AsyncWorker<> code is shown below,

type JobCompletedEventArgs<’T>(job:int, result:’T) =

inherit EventArgs()

member x.Job with get() = job

member x.Result with get() = result

type AsyncWorker<’T>(jobs: seq<Async<’T>>) =

// This declares an F# event that we can raise

let allCompleted = new Event<’T[]>()

let error = new Event<System.Exception>()

let canceled = new Event<System.OperationCanceledException>()

let jobCompleted = new Event<JobCompletedEventArgs<’T>>()

let cancellationCapability = new CancellationTokenSource()

/// Start an instance of the work

member x.Start() =

// Capture the synchronization context to allow us to raise events back on the GUI thread

let syncContext = SynchronizationContext.CaptureCurrent()

// Mark up the jobs with numbers

let jobs = jobs |> Seq.mapi (fun i job -> (job, i+1))

let raiseEventOnGuiThread(evt, args) = syncContext.RaiseEvent evt args

let work =

Async.Parallel

[ for (job,jobNumber) in jobs ->

async { let! result = job

syncContext.RaiseEvent jobCompleted (new JobCompletedEventArgs<'T>(jobNumber, result))

return result } ]

Async.StartWithContinuations

( work,

(fun res -> raiseEventOnGuiThread(allCompleted, res)),

(fun exn -> raiseEventOnGuiThread(error, exn)),

(fun exn -> raiseEventOnGuiThread(canceled, exn)),

cancellationCapability.Token)

/// Raised when a particular job completes

[<CLIEvent>]

member x.JobCompleted = jobCompleted.Publish

/// Raised when all jobs complete

[<CLIEvent>]

member x.AllCompleted = allCompleted.Publish

/// Raised when the composition is cancelled successfully

[<CLIEvent>]

member x.Canceled = canceled.Publish

/// Raised when the composition exhibits an error

[<CLIEvent>]

member x.Error = error.Publish

We have used [<CLIEvent>] attributes to mark these events for exposing to other .NET CLI languages. Since we are using Rx we need to have an event that inherits from System.EventArgs, JobCompletedEventArgs<T> does that here. The AsyncWorker is now ready to be used as a library for running parallel code.

Stock Quotes Reader

The Stock Quotes Reader defines a wrapper that does a request to the server (it would be yahoo finance here) and pull the stocks.

type StockAvailableEventArgs(stocks:string[]) =

inherit EventArgs()

member x.Stocks with get() = stocks

type StockQuotesReader(quotes:string) =

/// event raised for every job completed, this is easier to use in other CLI languages

let stockAvailableEvent = new Event<StockAvailableEventArgs>()

let httpLines (uri:string) =

async { let request = WebRequest.Create uri

use! response = request.AsyncGetResponse()

use stream = response.GetResponseStream()

use reader = new StreamReader(stream)

let lines = [ while not reader.EndOfStream do yield reader.ReadLine() ]

return lines }

// n – name, s – symbol, x – Stock Exchange, l1 – Last Trade, p2 – change in percent, h – high, l – low, o – open, p – previous close, v – volume

let yahooUri (quotes:string) =

let uri = String.Format("http://finance.yahoo.com/d/quotes.csv?s={0}&f=nsxl1hlopv", quotes)

uri

member x.GetStocks() =

let stocks = [httpLines(yahooUri quotes)]

stocks

member x.PullStocks() =

let stocks = x.GetStocks()

let worker = new AsyncWorker<_>(stocks)

worker.JobCompleted.Add(fun args ->

stockAvailableEvent.Trigger(new StockAvailableEventArgs(args.Result |> List.toArray))

)

worker.Start()

static member GetAsyncReader(quotes) =

let reader = new StockQuotesReader(quotes)

let stocks = reader.GetStocks()

let worker = new AsyncWorker<_>(stocks)

worker

[<CLIEvent>]

member x.StockAvailable = stockAvailableEvent.Publish

The above wrapper class does some interesting things,

· It has a async block code that yield returns a line of data based on the response stream.

· PullStocks will create async requests and raise the StockAvailable event whenever the async job is completed.

CEP Client

On the CEP client we would be using the below things,

· Syncfusion WPF GridDataControl – it works well with high speed data changes, keeping minimal CPU usage.

· Rx to create requests and update the ViewModel bound to the Grid.

Setup the application

The WPF application uses simple MV-VM by defining a StocksViewModel to hold stock data. The Stocks collection is bound to the Syncfusion WPF GridDataControl.

<syncfusion:GridDataControl Grid.Row="0" x:Name="grid"

NotifyPropertyChanges="True"

AutoPopulateRelations="False"

Width="Auto"

AllowGroup="True" ShowGroupDropArea="True"

AutoFocusCurrentItem="False"

ItemsSource="{Binding Model.Stocks}"

AllowEdit="False"

IsGroupsExpanded="True"

ShowAddNewRow="False">

</syncfusion:GridDataControl>

Using Rx to create requests

This real-time application requires real-time data that will be pulled over the wire for every 500 milliseconds. We would be making use of the IObservable to create a streaming request and repeat that over a time delay,

var stockReader = new StockQuotesReader(“MSFT+GOOG+INTL”);

var stockFeeds = Observable.Defer(() =>

{

stockReader.PullStocks();

var evt = from e in Observable.FromEvent<StockAvailableEventArgs>(stockReader, "StockAvailable")

select new { Stocks = e.EventArgs.Stocks.ToStockQuotes() };

var delayedEvt = Observable.Return(evt).Delay(TimeSpan.FromMilliseconds(delay));

return delayedEvt;

}).Repeat();

We now have a streaming real-time stock data pulled asynchronously over the web and shown on the Syncfusion GridDataControl.

clip_image004

If you want to get hold of the sample, send me a request.

Enabling Blend (/ VS designer) to identify ItemContainerStyle for custom control in Silverlight 3.0

When designing custom controls we would want the users to customize the appearance of the items that is added up in some derived form of ItemsControl. Say we have a property “ItemContainerStyle”, we would want that to be customized in Blend as it does for ListBox,

img

Lets say, we have a property called “MyButtonStyle”. To enable this property to be recognized by the designer, we would have to implement the StyleTypedPropertyAttribute in the implemented class,

[StyleTypedProperty(Property = "MyButtonStyle", StyleTargetType = typeof(MyButton))]
public class MyButtonItems: ItemsControl

That’s it. Hope this helps.

-Fahad

Being Very “Dynamic” – C# 4.0 – I

The world of .NET programming is heading towards a new direction, lots of frameworks, languages, services etc., to choose from. With all the rapid development, C# is also heading towards a new future, being to match the inter-op (or rather co-exist) with its Dynamic siblings (IronPython / IronRuby), it is rather fascinating to bridge the gap between two worlds, where the latter evolved from the previous one.

image

With C# 4.0, we have a new keyword “dynamic”, which offers the following features,

  • Binding with DLR
  • COM – Interop made easy
  • Conversions – between dynamic objects and other types are easy.

There may be scenarios, where constructing a dynamic object is absolutely necessary, Say, if we need to write some object reading from XML or some ATOM feed, we would normally parse the data to some predefined set (a static class). All is good in the world of static typing, and areas where you know exactly how your data (or Business object) would be. For dynamic scenarios, We have dynamic meta-data driven based programming, For instance, we could implement ITypedList, ICustomTypeDescriptor, or any derived version of PropertyDescriptor or any custom interface that defines the logic behind driving the meta-data.

The dynamic introduces a DynamicObject class that acts as an interface between the object store and the interaction between the CLR. You would simply have to inherit from the DynamicObject class and implement methods that would be used on the dynamic instance.

We will check out one simple sample that extends DynamicObject to have an object store,

public class MyDynamicObject : DynamicObject
{
private Dictionary<string, object> members;
public MyDynamicObject()
{
this.members = new Dictionary<string, object>();
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (this.members.ContainsKey(binder.Name))
{
result = this.members[binder.Name];
return true;
}
else
{
return base.TryGetMember(binder, out result);
}
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
if (!this.members.ContainsKey(binder.Name))
{
this.members.Add(binder.Name, value);
}
else
{
this.members[binder.Name] = value;
}
return true;
}
public override IEnumerable<string> GetDynamicMemberNames()
{
return this.members.Keys;
}
}

To use this we declare a dynamic instance,

dynamic d = new MyDynamicObject();
d.Name = “Hello World”;
Console.WriteLine(“Name : {0}”,d.Name);

With some help from the “reflector”, I was able to get an idea on how the dynamic objects were getting constructed in memory. And, thus came up an idea to write down a helper class that would automatically generate “CallSites” for Get/Set property,

public static class DynamicHelper

{
public static object GetValue(object dyn, string propName)
{
// Warning: this is rather expensive, and should be cached in a real app
var binder = Binder.GetMember(CSharpBinderFlags.None, propName,
dyn.GetType(),
new List<CSharpArgumentInfo> {
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
});
var getterSite = CallSite<Func<CallSite, object, object>>.Create(binder);
return getterSite.Target(getterSite, dyn);
}

public static void SetValue(object dyn, string propName, object value)
{
var binder = Binder.SetMember(CSharpBinderFlags.None, propName, dyn.GetType(), new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null), CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.LiteralConstant | CSharpArgumentInfoFlags.UseCompileTimeType, null) });
var setterSite = CallSite<Func<CallSite, object, object, object>>.Create(binder);
setterSite.Target.Invoke(setterSite, dyn, value);
}
}

Keeping my fingers crossed, we should probably get the dynamic keyword support for WPF GridDataControl (hopefully with Silverlight too).

Sample codes for the post can be downloaded here.

- Fahad

Embedding LINQ Expression for a method call

Consider evaluating an Expression at runtime, for some lame reason you had to call ToLower() on a string object, and create a predicate out of it. Using LINQ expressions simplifies the task of doing these things. Simply embed the custom Expression that would evaluate against the LINQ extension methods. Below is a sample MethodCallExpression to embed a ToLower() method inside a LINQ query,

private static MethodCallExpression GetToLowerMethodCallExpression(Expression memExp)
{
    var tolowerMethod = typeof(string).GetMethods().Where(m => m.Name == "ToLower").FirstOrDefault();
    var toLowerMethodCall = Expression.Call(
        memExp,
        tolowerMethod,
        new Expression[0]);
    return toLowerMethodCall;
}

Lets take a simple scenario, we would write a custom Expression (e) => some lambda functor, that would evaluate against a Contains predicate. We first would right down a normal functor that would return the value of a property by using a PropertyDescriptor,

Func<string, object> recordFunc = (columnName) =>
{
    var pd = properties.Find(columnName, false);
    return pd.GetValue(person1);
};

Since we cannot embed a full method inside an expression we split that into a Functor lambda, and then use that as a single expression given below,

Expression<Func<Person, bool>> e = (p) => p.Age1 == (int)recordFunc("Age2");

C# compiler generates a sequence of Expression calls to the lambda recordFunc (take a look in reflector with the compiled exe),

       Expression<Func<Person, bool>> e = Expression.Lambda<Func<Person, bool>>(Expression.Equal(Expression.Property(CS$0$0000 = Expression.Parameter(typeof(Person), "p"), (MethodInfo) methodof(Person.get_Age1)), Expression.Convert(Expression.Invoke(Expression.Constant(recordFunc), new Expression[] { Expression.Constant("Age2", typeof(string)) }), typeof(int))), new ParameterExpression[] { CS$0$0000 });

If we split this above expression into more meaningful method call, it should be as below,

public static LambdaExpression Contains(this object source, string propertyName, string propertyName2, Expression<Func<string, object>> recordFunctor)
{
    var type = source.GetType();
    var paramExp = Expression.Parameter(type, type.Name);
    var member = Expression.PropertyOrField(paramExp, propertyName);
    var member2 = Expression.PropertyOrField(paramExp, propertyName2);
    var convertedExp = Expression.Convert(Expression.Invoke(Expression.Constant(recordFunctor), new Expression[] { Expression.Constant(propertyName2, typeof(string)) }), member.Type);
    var binaryExp = Expression.Equal(member, convertedExp);
    var lambda = Expression.Lambda(binaryExp, paramExp);
    return lambda;
}

We can then use the above Contains extension method to embed a normal expression into LINQ predicate syntax or any LINQ extension method that requires a BinaryExpression to execute.

Download the sample here.

-Fahad

Loading XAML from C# – HACK!!!!

Ever wondered how to convert XAML to C# or to load a huge XAML content from C#, this post will possibly give you the best workaround to load it :) .

If you have large Brush values or large XAML content that you would want to instantiate and apply it dynamically thru C#, it is either you convert to string and use the XAML reader or convert everything to some equivalent C# code. One other way is you could put up the XAML content inside a resource dictionary and hook it into the generic.xaml file. For more info on generic.xaml you can check out creating control templates for WPF, which allows overriding templates through resource files.

Once you have the resource dictionary setup with the XAML content, Say as below,

<?xml version="1.0" encoding="utf-8"?>
<ResourceDictionary xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <DrawingBrush x:Key="Asterisk">
        <DrawingBrush.Drawing>
            <DrawingGroup>
                <DrawingGroup.Children>
                    <GeometryDrawing Brush="#FF000000" Geometry="F1 M 416.193,288.721L 406.118,
300.568L 406.212,300.848L 421.043,297.863L 421.043,307.284L 406.118,304.673L 406.025,304.952L 
416.193,316.426L 407.891,321.277L 402.574,306.818L 402.387,306.911L 396.977,321.277L 388.954,316.426L 
398.936,304.766L 398.936,304.579L 384.29,307.284L 384.29,297.863L 398.749,300.755L 398.842,
300.568L 388.954,288.814L 397.257,284.057L 402.48,298.329L 402.667,298.329L 407.984,284.057L 416.193,
288.721 Z "/>
                </DrawingGroup.Children>
            </DrawingGroup>
        </DrawingBrush.Drawing>
    </DrawingBrush>
</ResourceDictionary>

The above is a Asterisk symbol drawn with brush values. You could then create a WPF control instance and use the brush value as a background. Lets do that for a Border control,

private static ResourceDictionary GetResourceDictionary()
{
    ResourceDictionary rd = new ResourceDictionary();
    rd.Source = GetXamlConvertedValue<Uri>("Window1;component/Themes/Generic.xaml");
    return rd;
}

The above code simply creates a new Resource dictionary with the specified URI path. The GetXamlConvertedValue is simply a utility function that converts the string into the appropriate instance using TypeConverter,

public static T GetXamlConvertedValue<T>(string value)
{
    var converter = TypeDescriptor.GetConverter(typeof(T));
    if (converter != null)
    {
        return (T)converter.ConvertFromInvariantString(value);
    }
    return default(T);
}

 

Now we get the ResourceDictionary and get the DrawingBrush using the key “Asterisk”,

public static Brush BackgroundBrush
{
    get
    {
        var rd = GetCellRendererDictionary();
        var brush = rd["Asterisk"] as Brush;
        return brush;
    }
}

 

That’s it, We can simply get the value and set it as a background to the Border control. Like so any other content can be placed inside the ResourceDictionary and access it thru the Key/Value pair.

 

-Fahad

Dynamic LINQ Expressions – I

Generating dynamic LINQ expressions needs a bit of understanding on the IQueryable interface. Check out Matt’s series of posts on implementing the IQueryable interface –> LINQ Links. The strong drive for this post is that everything is strongly typed, of course we have the Dynamic LINQ library that comes in MSDN sample, but that comes with an over head of generating strings to perform operations. In many cases, strongly typed usage will result in controlling the flow more accurately.

Lets take a look at the extensions library that will be used for generating Expressions on a dynamic data source ( that implements IQueryable / IEnumerable ). In this post, we will look at generating OrderBy() query with different parameters defined in the Queryable class. Normally, there are helper classes that has implementation for generating LINQ expressions for IEnumerable and IQueryable interfaces. The Queryable class defines a wrapper thru which we can make calls to the IQueryProvider implemented for that source type (IQuerable / IEnumerable).

With our implementation,

  • We would go with making our objects AsQueryable().
  • Call the appropriate method from the Queryable class that defines the method.

OrderBy() query -

The OrderBy query generates a simple sort comparer with the property name that is present on the underlying IQueryable source,

/// <summary>
/// IQueryable expression for sorting in ascending.
/// </summary>
/// <param name="source"></param>
/// <param name="propertyName"></param>
public static IQueryable OrderBy(this IQueryable source, string propertyName)
{
    var sourceType = source.GetObjectType();
    ParameterExpression paramExpression = Expression.Parameter(sourceType, sourceType.Name);
    MemberExpression memExp = Expression.PropertyOrField(paramExpression, propertyName);
    LambdaExpression lambda = Expression.Lambda(memExp, paramExpression);
    return source.Provider.CreateQuery(
        Expression.Call(
            typeof(Queryable),
            "OrderBy",
            new Type[] { source.ElementType, lambda.Body.Type },
            source.Expression,
            lambda));
}

Taking a closer look at the functions,

Expression.Parameter – Defines the parameter on which the object is referred. Normally we would assign some parameter for the source in our LINQ expressions, Say for Northwind Orders table,

var orders = Orders.OrderBy( order => order.ShipCountry );

Like so, we can dynamically generate the above expression as,

var ordersQuerable = orders.AsQueryable();

var sortedOrders = ordersQueryable.OrderBy(“ShipCountry”);

You may want to perform multi-sorting on the underlying IEnumerable type, the other OrderBy related functions that have similar implementation are,

  • OrderByDescending
  • ThenBy
  • ThenByDescending

For building a big expression dynamically, all you have to do is loop thru the collection of sorted columns, and recursively build the expression by calling the OrderBy / OrderByDescending / ThenBy / ThenByDescending in some logical sequence.

Note: OrderByDescending / ThenByDescending will be generated only for IOrderedQueryable instance, So you need to maintain some kind of an instance that holds IOrderedQueryable from the return set of OrderBy / ThenBy.

Helper method:

This gets the underlying object type for the IQueryable source.

private static Type GetObjectType(this IQueryable source)
{
    var enumerable = source.GetEnumerator();
    var hasItem = enumerable.MoveNext();
    if (hasItem)
    {
        return enumerable.Current.GetType();
    }
    return null;
}

In the next posts, we will check out generating WHERE expression dynamically.

Hope this helps.

- Fahad

 

LINQ Data Table Extensions

Legacy applications which is to be migrated to a new platform (WPF, Silverlight etc.,) requires leveraging the underlying business layer too. We have IQueryable interface implemented for DataTable in System.Data.DataSetExtensions. There are couple of extension providers present,

  • DataTableExtensions
  • EnumerableRowCollectionExtensions

Data Table Extensions

This provides a list of functions to query with the DataTable. Most of them are casting functions,

  • AsDataView<T>
    • Accepts a EnumerableRowCollection and returns a DataView.
  • AsDataView
    • Accepts a DataTable and returns a DataView.
  • AsEnumerable
    • Accepts a DataTable and returns a EnumerableRowCollection, which is used for querying with DataRow collection.

Enumerable Row Collection Extensions

The LINQ provider is implemented for the DataRowCollection that is present in the DataTable.Rows property. The following are the LINQ extensions you can work with,

  • Select
  • OrderBy
  • OrderByDescending
  • ThenBy
  • ThenByDescending
  • Where
  • Cast

Select

Use the Select extension to get the query the required fields from the DataTable.

private static void SelectDataTable()
        {
            var dt = GetOrdersDataTable();
            var orders = dt.AsEnumerable().Select(o =>
                new
                {
                    OrderID = o.Field<int>("OrderID"),
                    CustomerID = o.Field<string>("CustomerID"),
                    EmployeeID = o.Field<int>("EmployeeID"),
                    OrderDate = o.Field<DateTime>("OrderDate"),
                    ShipCountry = o.Field<string>("ShipCountry")
                });
            foreach (var order in orders)
            {
                Console.WriteLine(string.Format("OrderID : {0} / CustomerID : {1} / EmployeeID : {2} 
/ OrderDate : {3} / ShipCountry : {4}", order.OrderID, order.CustomerID, 
order.EmployeeID, order.OrderDate, order.ShipCountry));
            }
        }

The Field<T> returns a strongly typed value from the underlying DataTable. You can also use SetField<T> 
to set the field value thru a strongly typed object.

OrderBy / OrderByDescending / ThenBy / ThenByDescending

Sort operations can be performed by using the above mentioned functions. Check out the code below,

 

private static void SortDataTable()
{
    var dt = GetOrdersDataTable();
    var orders = dt.AsEnumerable().OrderBy(r => r.Field<string>("ShipCountry"));
    var result = orders.ThenBy(r => r.Field<string>("CustomerID")).Select(o =>
        new
        {
            OrderID = o.Field<int>("OrderID"),
            CustomerID = o.Field<string>("CustomerID"),
            EmployeeID = o.Field<int>("EmployeeID"),
            OrderDate = o.Field<DateTime>("OrderDate"),
            ShipCountry = o.Field<string>("ShipCountry")
        });
    foreach (var order in result)
    {
        Console.WriteLine(string.Format("OrderID : {0} / CustomerID : {1} / EmployeeID : {2} 
/ OrderDate : {3} / ShipCountry : {4}", order.OrderID, order.CustomerID, order.EmployeeID, 
order.OrderDate, order.ShipCountry));
    }
}

Where

Filter operations require a predicate match to be passed. Check out the code below,
private static void WhereOperation()
{
    var dt = GetOrdersDataTable();
    var filteredOrders = dt.AsEnumerable().Where(o => o.Field<string>("ShipCountry") == "Brazil")
.Select(o =>
        new
        {
            OrderID = o.Field<int>("OrderID"),
            CustomerID = o.Field<string>("CustomerID"),
            EmployeeID = o.Field<int>("EmployeeID"),
            OrderDate = o.Field<DateTime>("OrderDate"),
            ShipCountry = o.Field<string>("ShipCountry")
        });
    foreach (var order in filteredOrders)
    {
        Console.WriteLine(string.Format("OrderID : {0} / CustomerID : {1} / EmployeeID : {2} 
/ OrderDate : {3} / ShipCountry : {4}", order.OrderID, order.CustomerID, 
order.EmployeeID, order.OrderDate, order.ShipCountry));
    }
}
With these functions we can easily translate our code to more typed collection and work 
with the legacy DataTable objects.
Note: The API documentation suggests that these API’s are used internally in the .NET FW and 
not intended to be used in our code directly :) .
Hope this helps.
-Fahad 
Follow

Get every new post delivered to your Inbox.