Null !== Steve

Steve Gentile's Tech Blog – Thoughts and Musings

Archive for the category “LINQ”

ADO.NET Data Services

I’m really impressed with what is happening around the ADO.NET Services (aka Astoria).

Think ‘RESTful’ url queries to entities in a way to abstracts out the particular underlying IQueryable provider.

This really does create a technology (as in Entity Framework vs. L2S vs. NHibernate.Linq) agnostic layer.

From the link above – a good set of video’s to watch (short and to the point):

How Do I …

More on Querying:  (how client queries relate back to the ADO.NET Services protocol RESTful queries)

ADO.NET Data Services – Querying with LINQ by Mike Taulty (and this link will show his other screencasts)

Further Reading:

Lost in Tangent has a series of Training blog posts

I do see ADO.NET Data Services as a great fit to behave as the service layer to your underlying domain entities model.

One thing that Mike Flasko demonstrates in the video (and Mike Taulty’s video) is the ability to query using several approaches…

I have two here:

      var entities = new BistroEntities(new Uri("http://localhost:56987/BistroWebDataServices.svc"));
      var query = from c in entities.Companies
                  where c.CompanyID.Equals(new Guid("56e0d889-5f54-4e2d-805b-9ba700e6b9e4"))
                  select c;
      var company = query.SingleOrDefault();
      company.Note = "Updated on " + DateTime.Now;
      entities.UpdateObject(company);
      entities.SaveChanges();

      DataServiceContext context = new BistroEntities(new Uri("http://localhost:56987/BistroWebDataServices.svc"));
      context.IgnoreMissingProperties = true;
      var q = context.Execute<Companies>(new Uri("/Companies", UriKind.Relative));
      var testCo = (from c in q
                    where c.CompanyID.Equals(new Guid("56e0d889-5f54-4e2d-805b-9ba700e6b9e4"))
                    select c).SingleOrDefault();
      testCo.Note = "Updated on " + DateTime.Now;
      context.UpdateObject(testCo);
      context.SaveChanges();
 

It is interesting to see the result of the ‘var’ query above:

{http://localhost:56987/BistroWebDataServices.svc/Companies(guid'56e0d889-5f54-4e2d-805b-9ba700e6b9e4')}
 

It is possible to drill down further, ie. to get all the contacts at a company assuming a 1 to many relationship:

{http://localhost:56987/BistroWebDataServices.svc/Companies(guid'56e0d889-5f54-4e2d-805b-9ba700e6b9e4')/Contacts}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 

You can make RESTful Uri queries, just as example of two:

http://localhost:56987/BistroWebDataServices.svc/Companies?$filter=startswith(Name,%20%27Test%27)
http://localhost:56987/BistroWebDataServices.svc/Companies?$orderby=Name
 

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

The first one queries the underlying Company entity object (which is mapped to the Companies table) and does a startswith query on the property of ‘Name’.

The second query does an orderby query by Company name.

Cool stuff  :)

(It’s no surprise that a decision was made by the RIA.NET Domain Services team to use ADO.NET DataServices as it’s underlying protocol).

For those with a close eye to detail, note the ‘unit of work’ with the ability to send the ‘UpdateObject’ – there is also the ability to send changes back with a batch update:

ie. 

entities.SaveChanges(SaveChangesOptions.Batch);
 

For an advanced topic, check out using ‘Modeling Data for Efficient Access at Scale’ w/Azure & ADO.NET DataServices – good video !

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

More on NCommon

Once again, I’m going to talk about NCommon.  I want to share some of Ritesh Rao’s posts on concepts that NCommon incorporates.  I’m very impressed with his architecture and it helps that he provides NCommon for NHibernate, Linq2Sql, Entity Framework (and I see he is venturing into EF v2).

My last post touched on this, but I’ll review it again:

  1. Framework for implementing a Unit of Work Pattern
  2. Framework for implementing a Repository pattern that utilizes Linq
  3. Framework for implementing a Validations and Business Rules
  4. Implementation of the Specification pattern using Expressions
  5. Utility class to help store application specific data in the Thread Local Storage / Current Web Request and AppDomain Level Storage
  6. Guard class that mimics common guard statements that verify parameter values and throws exceptions if values are not acceptable.

NCommon uses the Apache License 2.0

NCommon uses the  Microsoft.Practices.ServiceLocation – this allows you to plug in your dependency inversion container of choice.  

I have gotten rid of the generic IoC wrapper implementation from the library as it doesn’t seem necessary anymore with the rally behind the Common Service Locator project.

This is shown in the accompany tests setup:

[SetUp]
        public void SetUp()
        {
            EFUnitOfWorkFactory.SetObjectContextProvider(() =>
            {
                var context = new TestModel();
                return context;
            });
            var locator = MockRepository.GenerateStub<IServiceLocator>();
            locator.Stub(x => x.GetInstance<IUnitOfWorkFactory>())
                   .Return(new EFUnitOfWorkFactory()).Repeat.Any();
            ServiceLocator.SetLocatorProvider(() => locator);
        }

NCommon sets the object context and implements the IUnitOfWorkFactory (the above shows with Entity Framework).

An example of how this is used can be found in the UnitOfWorkScopeTransaction class (UnitOfWorkScopeTransaction.cs- trunk/NCommon/src/Data)

ie. the ‘GetTransactionForScope’ method to retrieve the UnitOfWorkFactory:

 
var factory = ServiceLocator.Current.GetInstance<IUnitOfWorkFactory>();
var newTransaction = new UnitOfWorkScopeTransaction(factory, isolationLevel);
newTransaction.AttachScope(scope);
CurrentTransactions.Add(newTransaction);
return newTransaction;
 

The NCommon tests highlight the features of NCommon as well, including Fetching Strategies, Specification, Repositories, and Unit of Work.

Let’s look at some of Ritesh’s posts…

http://www.codeinsanity.com/2009/04/repository-pattern-thoughts.html

Some key items in this post to quote:

repositories should really represent a queryable data store that doesn’t abstract away queries behind methods that some unfortunate developer has to maintain and evolve, but rather allow consumers of the repository to query it directly. Hence why NCommon relies on repositories to implement the IQueryable interface to provide a query infrastructure directly on top of NCommon repositories.

I think this is an important piece to understand, and Ritesh follows up with the comment:

The approach I would take is rather than exposing the infrastructure requirements in the query object, I’d like it to take in an IQueryable and return back a IQueryable. This will allow chaining of queries by multiple of such Query objects without exposing any infrastructure concerns.

…

The problem with exposing ICriteria, or any other infrastructure component, to all layers of the application is that eventually a lot of infrastructure concern creeps into layers of the application where they don’t belong. I dislike the idea of having the expose ICriteria to the UI for adding paging and sorting on top of the query encapsulated by ICriteria.

That being said, in my opinion IQueryable is best suited for this job. Its a framework level member that is infrastructure agnostic, provides a very nice way to chain queries together and encapsulates our query requirements rather well.

Read more…

JSING

Quick bump for ‘JSING’, Linq to Objects for Javascript – http://www.codeplex.com/jsinq

Very cool, as a big fan of Linq, it’s cool to see someone building it for javascript.

(I haven’t used it yet, but I like the premise behind it)

What JSING can do…

  • Write arbitrarily complex queries against JavaScript arrays, DOM node lists or your own enumerable types
  • Find elements in the HTML DOM tree using SQL-like queries
  • Dynamically create HTML elements from JSON you have received via XMLHttpRequest in a declarative manner
  • Tinker with XML and turn it into something else
  • Combine it in interesting ways with the JavaScript-/Ajax-frameworks you are already using
  • Write less code by exploiting the power of declarative programming
  • And for the ambitious: write raytracers, monadic parser combinators, etc.

LINQ – Grouping Feature

I have a love affair… no, not that kind – the LINQ kind  :)    It makes what is normally ‘complex’ – into fun and rather easy to do.

Let’s take sorting.

ie. I have a list of many items from a database table that I retrieve.  Then I need to group all the ‘same types’ so I can do some reporting on them.

I run a fun aircraft ww2 flight sim website for flight simulator game ‘IL2: Sturmovik’.  I was asked recently to show the ‘kills to death’ ratio of the different aircraft flown by the pilots in this sim.

My database stores a list of these air summaries per mission – so you might have something like this:

KillerClass KilledClass

FW190       Spitfire

FW190       P47

P47           109

 

So the first step is to ‘group’ the Aircraft – do a ‘kill count’:

IEnumerable<IGrouping<string, MisAirSummary>> AirSummaryByKillerClass = airSummary.GroupBy(a => a.KillerClass);

(where airSummary is the results from my LINQ Query – a List<MisAirSummary>)

Simple!

So, how do I display the results?  (Note, in this sample I break some ‘Business layer’ vs. ‘UI Layer’ concepts… but that isn’t the topic is it…  ;) )

(I’m using ASP.NET MVC…)

I pass the two collections down to the view in the ViewData (normally I wouldn’t do it this way, but this is a quick and dirty sample)

note the ‘foreach (var items in AirSummaryByKillerClass.OrderBy(p => p.Key))’  line below.  Each ‘items’ is a

System.Linq.Lookup<string,FSData.MisAirSummary>.Grouping :

the AirSummaryByKillerClass is a :

{System.Linq.GroupedEnumerable<FSData.MisAirSummary,string,FSData.MisAirSummary>}

The ‘items.Key’ is the grouped by value, and has a list of the values.  Note is it using the ‘Lookup’ feature of Linq. 

 

<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<%
    List<FSData.MisAirSummary> airSummary = ViewData["AirSummary"] as List<FSData.MisAirSummary>;
    IEnumerable<IGrouping<string, FSData.MisAirSummary>> AirSummaryByKillerClass = ViewData["AirSummaryByKillerClass"] as IEnumerable<IGrouping<string, FSData.MisAirSummary>>; %>



    <br /><br />
    <table id="stats" class="tablesorter" style="width:600px">
    <thead>
        <tr>
            <th>Type</th>
            <th>Kills</th>
            <th>Deaths</th>
            <th>K/D Ratio (x/1)</th>
        </tr>
    </thead>
    <tbody>
<% foreach (var items in AirSummaryByKillerClass.OrderBy(p => p.Key))
   { %>

            <tr>
            <td>
                <%
                    int kills = items.Count();
                    int deaths = airSummary.Where(s => s.KilledClass == items.Key).Count();
                    float kdRatio = 0.0F;
                    if (deaths != 0) { kdRatio = float.Parse(kills.ToString()) / float.Parse(deaths.ToString()); }
                %>
                <b><%= items.Key %> </b>

            </td>
            <td><%= kills.ToString() %></td>
            <td><%= deaths.ToString() %></td>
            <td><%= kdRatio.ToString("F")%></td>
            </tr>

<%} %></tbody> </table>
</asp:Content>
So there you have it - quite easy to implement!  (see it in action...) LINQ does the hard work for me, so I can just solve the problem at hand.

Shifting directions…

Sometimes a refactor can be painful, but there is a light at the end of the tunnel, especially when you know the refactor will be a good move.

I really enjoyed working with Spring.NET but decided to shift to a simplier* model (Sharp Architecture).  A positive is that my code was separated well enough that the impact was minor.  (when I say ‘simplier’ – most that I’m only using a small subset of Spring.NET – NHibernate session management/Transactional management/Dao injection into my controllers)

One move led to another, and I made the jump to NHibernate 2.0.  While I was frustrated at being able to find the installer for NHQG 1.9 (there is one for 1.8 with NH 1.2) – I realized that the NHibernate direction is moving to NHibernate.Linq… so, hey, let’s try it out.

Let’s compare:

ICriteria:

            ICriteria crit = Session.CreateCriteria(typeof(EmployeeQuerySet))
                .Add(Expression.Like("LastName", lastName, MatchMode.Start));
            return crit.List<EmployeeQuerySet>();

 

NHQG:

return this.FindAll(Where.EmployeeQuerySet.LastName.Like(lastName, MatchMode.Start), OrderBy.EmployeeQuerySet.LastName.Asc);

 

NHibernate.Linq:

                        var query = from emp in Session.Linq<EmployeeQuerySet>()
                        where emp.LastName.StartsWith(lastName)
                        orderby emp.LastName ascending
                        select emp;

I personally like the Linq syntax because I’ve been using it since it was available to replace all my collection delegate calls.

So far so good on the refactoring…  :)

(By the way, I really haven’t seen the value of something like EF or Linq to SQL when I have the power of NHibernate and NHibernate.Linq)

Learn more about NH 2.0 here

Stepping into Silverlight…

Well, I’ve decided it’s time to learn to use Silverlight.  I’m installing the Silverlight 2.0 and latest Blend software (along with Zoom) to run it.

This will be my first step into XAML/WPF.  If anyone has some good reading recommendations or tutorials worth going through, email me or post me some links here.

 

UPDATE: wow.  ok, I started in on some tutorials.  Silverlight/Blend/VS 2008 actually make a good combination.  I still don’t like that I can’t use Blend ‘inside’ VS 2008 – or that VS doesn’t just include this functionality (it’s silly to be popping back and forth between the two).  (Blend isn’t really needed, but it just makes it easier at times).

So, Silverlight isn’t really that difficult at all  :)   I’m having fun with it.  I did create a DeepZoom test, I have a map from a flight combat sim game and I wanted to try out the Deep Zoom composer – it basically takes an image and adds zooming scrolling capability to it.  Here is an example:

Kuban Zoom Test

Secondly, I create a sample after listening to this 15 minute video of a Silverlight/WCF/LINQ to SQL control that queries one of my database tables.  Not too shabby – it helps that they have included the Datagrid in Silverlight 2.0. 

The download of Silverlight is extremely small – I’m impressed they can stuff that much ‘.net framework’ into such a small download….  :)

 

UPDATE 2: Some very important tips to using LINQ to SQL with Silverlight (ie mostly for updates – since it’s disconnected with the WCF/WebServices)

1. unless you roll your own, you will have to add a timestamp column to your database tables… (yikes)

2. make sure you set that timestamp field to “Update Check” = “Always”

3. Use the following to ‘attach/refresh’

public void Update(Customer customer) { NorthwindDataContext context = new NorthwindDataContext(); context.Attach(customer); context.Refresh(RefreshMode.KeepCurrentValues, customer); context.SubmitChanges(); }

4. Lastly – and very important – click on the LINQ to SQL designer and set the ‘Serialization Mode’ to Unidirectional

Thought I’d share these pain points – all to get the disconnected, WCF, with Linq to Sql working with Silverlight  :)

Linq

Some general links to the LINQ crowd:

1. LinqKit : “LINQKit is a free set of extensions for LINQ to SQL power users”

2. LINQ over NHibernate : Ayende has built a NHibernate Linq provider.

His project includes a comprehensive set of tests that run against Northwind database. A secondary benefit is he shows in his tests different linq queries as well :)

LINQ to SQL – using Linq for SQL ‘Like’ statement

I’m really enjoying using LING to SQL, mostly because of the new .NET framework 3.5 LINQ features.

My latest find was ‘how do I make a ‘LIKE’ query using LINQ to SQL’ ?

Well, it was almost too intuitive :)

FSDALDataContext dc = new FSDALDataContext(connectionString);

            var pilotStats = from p in dc.CurrPilotStats
                             where p.PilotName.Contains(pilotName)
                             orderby p.Missions descending
                             select p;
            return pilotStats.ToList();
In the example above the equivalent SQL is
FROM tblCurrPilotStats WHERE (PilotName LIKE @ParamPilotName) ORDER BY Missions DESC"

If you are wanting a startswith or endswith, it’s the same syntax p.PilotName.Startswith(…)

A bit off subject, but I can approach queries with the syntax above, or use lamba:

FSDALDataContext dc = new FSDALDataContext(connectionString);
            var g = dc.MisAirSummaries.Where(air => air.MissionNum == decimal.Parse(missionID));
            return g.ToList();

Notice both statements have the ‘ToList()’ – the actual query is executed at that point.

Extension Methods

In my last post I talked about using Lamba expressions. C# 3.0 includes extension methods.

 

List<Person> people = new List<Person>();
            people.Add(new Person("Steve"));
            people.Add(new Person("Jake"));
            people.Add(new Person("Tyler"));
            people.Add(new Person("Evan"));
            people.Add(new Person("Gina"));

int count = people.Count(person => person.FirstName.ToUpper().Contains("N"));
Assert.That(count, Is.EqualTo(2));

As you know, List<T> does not include by default a ‘Count’ method.

When we include a reference to System.Linq, it includes extensions that get added to any type of IEnumerable class.

Some more examples include:

  • Any – Returns true if any items meet the criteria.
  • Average – Returns an average of the field specified.
  • Count – Pretty straight forward (as shown above).
  • Where – Just like SQL, you can return a subset based on a condition.
  • OrderBy – Also just like SQL.

Let’s give some examples based on the list above:

bool any = people.Any(person => person.FirstName.Contains(“Steve”));

Assert.That(any, Is.True);

IOrderedEnumerable<Person> peopleSearch = people.Where(person => person.FirstName.Contains(“a”)).OrderBy(person => person.FirstName);

Using ‘where’ with ‘OrderBy’:

IOrderedEnumerable<Person> peopleSearch = people.Where(person => person.FirstName.Contains(“a”)).OrderBy(person => person.FirstName);

So, how do you create an Extension method?

Let’s create a simple example where you would want to validate the string email address, for example:

 

string email = "steve@steve.com";
email.IsValidEmailAddress();

As we know, string doesn’t contain a ‘IsValidEmailAddress()’, we can add this functionality by extending string using a static class/method:

ie.

 

 public static class ExtensionSample
{
    public static bool IsValidEmailAddress(this string s)
    {
        Regex regex = new Regex(@"^[w-.]+@([w-]+.)+[w-]{2,4}$");
        return regex.IsMatch(s);
    }
}

There is much more to this than I’ve shown here, but it should be a good start!

Post Navigation

Follow

Get every new post delivered to your Inbox.