Posts Tagged ‘LINQ’

WPF-book is now available in stores, maybe you win a free one @MSUGS

Monday, June 30th, 2008

Since last week my German WPF-book is available in stores. You find more details about the book and some snippets of chapter 1 and chapter 14 on Galileo Computing. You can order the book on the Galileo Comuting-Website or on amazon.de and other stores.

For any questions about the book, write a comment to this post or use the contact-form of my homepage. If you’ve already got the book, I’m looking forward to your feedback.

What’s going on next:

Free MSUGS-Event about developing Custom Controls with the chance to win a WPF-book:
On Wednesday, 20th August, you can visit a free event in cooperation with the Microsoft User Group Switzerland (MSUGS) about developing Custom Controls with WPF. The event will be in Zurich @Trivadis (Europastrasse 5). You find more details about the event here. At the end of this event, you can win one WPF-Book for free.

WPF-Course @Trivadis:
If you want to know more things about WPF-Programming, take a look at the 3-day WPF-course at Trivadis, which you find here. If you take this course, you’ll get a WPF-book, the Trivadis course-material, and everything you need to become a rich & famous WPF-Programmer. ;-)

DataAccess in the time of LINQ:
Christoph Pletz and I are working on a TechnoCircle - a one day event you can visit in the second half of this year @Trivadis - about DataAccess in the time of LINQ. This TechnoCircle does not only show you how LINQ works, it shows how to implement a Data Access Layer in the time of LINQ in a Three-Layer-Architecture. It also discusses the usage of LINQ to SQL vs. Entity Framework vs. DataSets etc. As soon as you can register for the TechnoCircle, you’ll find more infos on the Trivadis-website and of course here on my blog…

TechEd Developers 2007 in retrospect - Wednesday

Monday, November 26th, 2007

Wednesday at TechEd was another "linqy" day for me. In the morning I joined the session "LINQ to XML", with speaker Mike Taulty. With LINQ to XML there is a new XML-API as Part of .NET 3.5 which sits in the namespace System.Xml.Linq. LINQ to XML makes it easy to create and edit XML documents without using additional syntax like XPATH or XSLT, but, of course, LINQ to XML won’t replace the existing APIs implemented in classes like XmlDocument, XmlReader, XmlWriter or XPathNavigator. It’s just another XML-API that let’s you use LINQ queries on top of XML.

Mike Taulty showed that LINQ to XML is much closer to XML than the other XML-APIs as part of the .NET Framework. When you create a XML-document with the new API, you can see that your C#-Code is really close to the XML (if you format your code like below and additionally put the XAttribute-Elements on the same line as the XElements they belong to (I hadn’t enough space to do so :-))):

XDocument doc =
  new XDocument(
    new XElement("TrivadisLocations",
      new XElement("Location",
        new XAttribute("City","Basel"),
        new XElement("Consultants",
          new XElement("Consultant",
            new XAttribute("FirstName", "Thomas"),
            new XAttribute("LastName", "Huber")
          ),
          new XElement("Consultant",
            new XAttribute("FirstName", "Christoph"),
            new XAttribute("LastName", "Pletz")
          )
        )
      ),
      new XElement("Location",
        new XAttribute("City", "Freiburg"),
        new XElement("Consultants",
          new XElement("Consultant",
            new XAttribute("FirstName", "Thomas"),
            new XAttribute("LastName", "Wukasch")
          )
        )
      ),
      new XElement("Location",
        new XAttribute("City","Zürich"),
        new XElement("Consultants",
          new XElement("Consultant",
            new XAttribute("FirstName", "Patrick"),
            new XAttribute("LastName", "Spieler")
          )
        )
      )
    )
  );

doc.Save("locations.xml");

The XML generated from the code above looks like this:

<?xml version="1.0" encoding="utf-8"?>
<TrivadisLocations>
  <Location City="Basel">
    <Consultants>
      <Consultant FirstName="Thomas" LastName="Huber" />
      <Consultant FirstName="Christoph" LastName="Pletz" />
    </Consultants>
  </Location>
  <Location City="Freiburg">
    <Consultants>
      <Consultant FirstName="Thomas" LastName="Wukasch" />
    </Consultants>
  </Location>
  <Location City="Zürich">
    <Consultants>
      <Consultant FirstName="Patrick" LastName="Spieler" />
    </Consultants>
  </Location>
</TrivadisLocations>

OK, of course, writing XML is not such an amazing thing if you have a query language like LINQ. Reading XML would be more exciting. So let’s say you want to read the XML-file we’ve just created above and you want to get out each location-City where a "Thomas" works. You can just load the document by calling the static Load-Method of the XDocument-class and create a query on top of that document:

XDocument doc = XDocument.Load("locations.xml");

var query =
  from c in doc.Descendants("Consultant")
  where c.Attribute("FirstName").Value == "Thomas"
  select c.Ancestors("Location")
         .Attributes("City").First().Value;

foreach (string city in query)
{
  Console.WriteLine(city);
}

The Output on the Console is
> Basel
> Freiburg

With the query above you get the cities more than one time if there are more than one “Thomas” in one location. Fortunately the XML above has exactly one or none in each location. By using a simple group by you won’t get any cities more than one time, even if there are more than one “Thomas” in a location:

XDocument doc = XDocument.Load("locations.xml");

var query =
  from c in doc.Descendants("Consultant")
  where c.Attribute("FirstName").Value == "Thomas"
  group c
  by c.Ancestors("Location")
      .Attributes("City").First().Value
    into grouping
    select grouping.Key;

foreach (string city in query)
{
  Console.WriteLine(city);
}

In the afternoon I joined the Session "Entity Framwork: Application Patterns", with speaker Pablo Castro. If you’ve already had a look at the Entity Framework, maybe you were just thinking about the DataContext class. What is it with this class? Do you keep it in a stateful DataAccessLayer, or is it stateless and you create it each time the BusinessLayer accesses you DataAccessLayer? Pablo’s answer is that it’s stateless. The DataContext knows the structure and metadata of the underlying database, but it has no state and it is very thin. So in every method like "GetCustomerById(Guid customerID)", you would create a new instance of the DataContext. Normally you would create the DataContext in the header of a using-block, so that it’s automatically disposed at the end of that block.

TechEd Developers 2007 in retrospect - Tuesday

Saturday, November 17th, 2007

On the second day at TechEd, the first session I joined had the title "Cool Looking 3D visualizations with Windows Presentation Foundation (WPF)" (Speaker: Dennis Vroegop).

The WPF has a "built-in" 3D-API, and this session showed what you can do with 3D in your business applications. The 3D-API of WPF isn’t adequate for great 3D Games. For Games you should use Managed DirectX that has a much better performance than WPF’s 3D-API (which is build on a "Media Integration Layer" (Milcore) that is built on top of DirectX). WPF’s 3D-API is an easy way to bring some great 3D effects to your business applications. This session showed beside the basics of 3D an example how 3D can be used for a better data representation. The used example showed a 3D map and represented product-data for different locations as 3D-objects.

LINQ to SQL: Accessing Relational Data with Language was the session I joined next, speaker was Luca Bolognese. LINQ to SQL is the easiest way to access a relational database with .NET 3.5. In LINQ to SQL entity classes are mapped directly to tables in the database. For each table a class. To query a database a developer hasn’t to know anything about SQL. The query is defined in C# with the LINQ-Syntax introduced in C# 3.0. The SQL sent to the database is generated automatically. Let’s look at a very simple example to load some data.

To load data with LINQ to SQL, the first thing you have to do is to add a reference to the assembly System.Data.Linq.dll to your project and then create your entity classes. The entity classes are mapped to a table in the database via the attributes Table and Column contained in the namespace System.Data.Linq.Mapping. Of course Visual Studio 2008 contains a designer, that allows you to drag’n'drop tables from the server explorer to the designer surface, and it’ll create the entity classes for you. In this example I’ll just use a manually created class:

[Table(Name="Friends")]
class Friend
{
  [Column(IsPrimaryKey=true)]
  public Guid FriendID;
  [Column]
  public string Name;
  [Column]
  public int Age;
}

As shown above, the Class Friend maps to the table Friends as specified with the TableAttribute. You could also specify the TableAttribute without setting the Name-Property, then your classname must match exactly the table name in the database. The table Friends in the database contains the columns FriendID, Name and Age. You see exactly the same columns in the Friend class. The ColumnAttribute also has a Name-Property that you can use if your .NET field or property doesn’t match the columnname from the table in the database. The column FriendID is additionally marked as primary key. Only those fields/properties you’ve marked with an ColumnAttribute are persisted in the database and could be loaded from database via LINQ to SQL. Ok, so far we’ve created a Friend class mapping to a Friends table in the database.

Now we can already connect to the Database and query the Friends table by using the DataContext class. The DataContext is used similar to the ADO.NET Connection. In fact the DataContext constructor takes a connection string and internally uses an IDbConnection. The DataContext is responsible to translate the queries you write in LINQ against your objects to SQL. To view the SQL the DataContext has generated for you, assign a TextWriter to its Log-Property. In the following snippet I’ve just assigned the standard output stream of the console to the Log-Property of the DataContext. I’ve passed in a connection string for the database “hubethomsDB” in my local SQLEXPRESS instance to the constructor of the DataContext:

DataContext ctx = new DataContext(
  @"Server=.\SQLEXPRESS;Database=hubethomsDB");

ctx.Log = Console.Out;    

In LINQ to SQL every table is represented by a Table-Collection of type System.Data.Linq.Table<TEntity>. As the name implies, the Table itself is identified by the entity class. Back to our sample, you get a Table-Collection for the table Friends by calling the generic Method GetTable<TEntity> on the DataContext and give the Method the Friend entity as the generic argument:

Table<Friend> friends = ctx.GetTable<Friend>();

On the received Table-Collection, you can create a query in LINQ. And now there’s a big difference to SQL. The query isn’t executed by the statement you see below, it’s only created.

var query = from f in friends
            where f.Age < 30
            select f;

The query gets executed, when you iterate over it, not before!!!

foreach (var friend in query)
{
  Console.WriteLine(friend.ToString());
}

The SQL generated by the DataContext is shown in the console window below. As you can see in the generated SQL, the data is filtered on the database and not in .NET.

20071117_LINQToSQL

Luca Bolognese said in his session, that Microsoft has tried every possible query and the DataContext was able to create a good SQL statement out of it. The tests have been done by people working for long times in the sqlserver team. Time to try some real complex queries on it and check it out.

What is the benefit of LINQ to SQL, when classes are mapped directly to tables?

The biggest benefit out of LINQ to SQL is that a developer hasn’t to know anything about SQL, he can specify and execute his query directly in C#.

Conclusion: I haven’t tested real complex SQL statements with LINQ to SQL up to now. Interesting are also things like indexes used by the generated query etc.