Bill Blogs in C#

Bill Wagner discusses C#, LINQ, and other items of interest

November 2007 - Posts

 I try to do more original writing here than posting links, but this is too good not to reference.

http://channel9.msdn.com/ShowPost.aspx?PostID=358968

 Brian Beckman is one of my favorite experts from Channel 9.  He's a real rocket scientist, but that's not why I like hi videos.  He's not trying to be a rock star pesonality.  Instead, he's great in that "everyone that views this will learn something." 

I want you to watch this video at least twice.  First, watch it to understand monads, functional programming, and the kinds of problems for which it was designed. You'll understand the concepts better afer each viewing.

 After you do that, watch it to improve your speaking skills. Notice how Dr. Beckman takes concepts that are unfamiliar to you and makes them clear. The video is not about making you think Dr. Beckman is smart (although you will). It's not about how hard these concepts are.  Instead, it's about how easy these concepts are to unerstand once Dr. Beckman explains them to you.  It's abot how you'll understand monads, monoids, functions, and LINQ syntax better after you watch this.

You can learn some computer science theory, and improve your speaking skills at the same time.  It's a great use of an hour.

Oh, and after you do that, read through the comments on the Channel9 page.  There's been quite the ongoing discussion.

Posted by wwagner | 1 comment(s)
Filed under: , , ,

A bit out of date, perhaps, but the Coding4Fun blog contains a vista gadget that changes your background wallpaper at regular intervals:

http://blogs.msdn.com/coding4fun/archive/2007/07/16/3904885.aspx

 Point the gadget at a directory containing photos and you're off to the races.

Posted by wwagner | 3 comment(s)
Filed under: ,

Toward the bottom of the LINQ to SQL samples is a set called "advanced". I'm not sure I like that title, because "Advanced" really should read "Things you just haven't done yet".

The first set of samples gives you a glimpse into the deeper goo inside the Linq to SQL libraries. And, understand that none of this is hidden from you. Come to my CodeMash talk on IQueryProvider and you'll see that you can build the same type of capability into your own data sources.

But back to the content. Here's the entire advanced sample 1:

public void LinqToSqlAdvanced01()
{
ParameterExpression param = Expression.Parameter(typeof(Customer), "c");
Expression selector = Expression.Property(param,
typeof(Customer).GetProperty("ContactName"));
Expression pred = Expression.Lambda(selector, param);

IQueryable<Customer> custs = db.Customers;
Expression expr = Expression.Call(typeof(Queryable), "Select", new Type[] {
typeof(Customer), typeof(string) }, Expression.Constant(custs), pred);
IQueryable<string> query =
db.Customers.AsQueryable().Provider.CreateQuery<string>(expr);

System.Data.Common.DbCommand cmd = db.GetCommand(query);
Console.WriteLine("Generated T-SQL:");
Console.WriteLine(cmd.CommandText);
Console.WriteLine();

ObjectDumper.Write(query);
}

 

 

There's quite a bit happening here. The first three lines build a lambda expression that evaluates a customer and returns the contact name.

The next short block builds a method call expression that selects the return value from the Lamdba expression already created for each customer in the input sequence. That method call expression is used to create a query, typed as an IQueryable<string> (so it's a query that returns a sequence of strings).

The db.GetCommand() call is a nice debugging aid that lets you see the T-SQL generated by the Linq to SQL libraries for that query.

Finally, this sample just executes the query.

You can compose other expressions as well.

Here's a Where query:

ParameterExpression param = Expression.Parameter(typeof(Customer), "c");
Expression right = Expression.Constant("London");
Expression left = Expression.Property(param,
typeof(Customer).GetProperty("City"));
Expression filter = Expression.Equal(left, right);
Expression pred = Expression.Lambda(filter, param);

Once again, it's building code. param is a parameter expression saying that 'c' is a Customer.

Right is a constant expression, the string "London".

Left is a property evaluation expression, the string value of c.City (remember that 'c' is a customer).

Filter is a boolean expression that returns true if left (the string "London") and right (the value of c.Customer) are equal.

And finally, pred composes a lambda expression that returns true for any customer whose city is London.

See, this 'advanced' stuff, while not as simple as typing 'where City == "London" ' is not that bad. And, it's rather useful in some applications to be able to construct your query at runtime.

That's about it for today. There are other samples here, but they point out some small (but important) features that are quite simple once you see them.

 

Posted by wwagner | 3 comment(s)
Filed under: , ,

Toward the bottom of the LINQ to SQL samples, you'll find several methods discussing the DataContext class. This is an important class that provides the interface between your code and the physical database storage.

There are also some convenient methods that can make it easier for you to initialize a LINQ-enabled application for the first time.

One of the startup tasks would be to check for a database's existence, and create that database if necessary.

This snippet of code shows you how to initialize a DataContext – derived object and determine if the corresponding database exists:

string userTempFolder = Environment.GetEnvironmentVariable("Temp");
string userMDF = System.IO.Path.Combine(userTempFolder, @"NewCreateDB.mdf");
NewCreateDB newDB = new NewCreateDB(userMDF);

if (newDB.DatabaseExists())
Console.WriteLine("Error: NewCreateDB DB exists");
else
Console.WriteLine("NewCreateDB DB does not exist");

The code above creates a string representing the path to a database, and creates a DataContext for that database. Once the context is created, the DatabaseExists () method will tell you if the database exists.

Of course, if the database doesn't exist, you probably want to create it:

NewCreateDB newDB = new NewCreateDB(connStr);
newDB.CreateDatabase();

 

And, just because you might need to, you can delete the database:

newDB.DeleteDatabase();

 

For debugging purposes, the DataContext class contains a Log property that if set to a valid stream, will provide trace information that you can use to understand the underlying code in your LINQ to SQL applications.

db.Log = this.OutputStreamWriter;

 

To turn it off, just set the Log property to null:

db.Log = null;

 

Finally, I'll provide a glimpse into some of the topics I'll cover in one of my talks at CodeMash: IQueryProvider and how some of the underlying LINQ capabilities are provided for you by a datasource.

Here's a rather advanced bit of code that builds a query:

var c1 = Expression.Parameter(typeof(Customer), "c");
PropertyInfo City = typeof(Customer).GetProperty("City");

var pred = Expression.Lambda<Func<Customer, bool>>(
Expression.Equal(
Expression.Property(c1, City),
Expression.Constant("Seattle")
), c1
);

IQueryable custs = db.Customers;
Expression expr = Expression.Call(typeof(Queryable), "Where",
new Type[] { custs.ElementType }, custs.Expression, pred);
IQueryable<Customer> q =
db.Customers.AsQueryable().Provider.CreateQuery<Customer>(expr);

 

The purpose of the code is to build a query, or a set of code as an Expression which can be parsed, compiled, or executed. It's the key to treating code as data in LINQ.

The first two lines show a bit of low-level grunt code necessary to build a query. The first line initializes c1 to an Expression object that represents a parameter. The name of the parameter is 'c', and the type of the parameter is a customer. That's a rather simply example of an expression (a ParameterExpression, to be precise).

The next line finds the PropertyInfo object representing the 'City' property of a customer. That should be clear to anyone that has used Reflection in the past.

Now comes the cool part. The predicate, 'pred', defines the lambda expression that finds all customers where the city is Seattle. It's the code that gets built when you write "from c in Customers where c.City == Seattle". Pred is an Expression<Func<Customer,bool>>. That means it is an expression which contains a function that has one parameter (of type Customer), and returns a Boolean. The body of the lambda compares the city property to the constant "Seattle". Fun, huh?

Well, now you can execute the expression. Custs is the Customers table as an IQueryable. IQueryable behaves (on the outside) similar to the IEnumerable interface. However, IQueryable provides some extra goodness.

That extra goodness is the ability to take an expression and execute it. First, you need to define the expression. That next line of code creates a method call expression on the Customers table, using the predicate defined a bit earlier, and the "Where" method.

The last line creates a query using that expression on the customers table.

It's complicated code, but it's important to understand from the standpoint of running queries in the most efficient way. An implementor of IQueryable can determine the best way to implement the algorithm defined by a query expression. In the case of LINQ to SQL, this is the mechanism that is used to translate your lambda expressions and methods into T-SQL code that is executed in the database engine.

Posted by wwagner | with no comments
Filed under: , ,

This is great news. The hard working speaker committee today confirmed that Scott Hanselman will be giving one of the keynotes at CodeMash in January 2008. (www.codemash.org).

That's beginning to build quite the history and commitment. Last year, Scott Guthrie came, and this year Scott Hanselman. And, because CodeMash's purpose is bringing together developers from different technology communities together, CodeMash had Bruce Eckel and Neal Ford speaking last year. The CodeMash speakers committee is going to fill those other two keynotes with similar quality folks again this year.

(Of course, you should view this as a subtle hint to go register)

Posted by wwagner | 1 comment(s)

It took a while, but the new Visual Studio Magazine online site (www.visualstudiomagazine.com) is now live.

All my columns for the C# Corner are found here: http://visualstudiomagazine.com/columns/columnist.aspx?columnistsid=54

 

Posted by wwagner | 2 comment(s)
Filed under: , ,

This year, I've had two sessions accepted for Code Mash:

Real World C# 3.0

Now that the release of Visual Studio 2008 is imminent, it’s time to look at how these new features will make you more productive.  New toys are great, but this session will teach you how these new features can help you be more productive in your daily development. More importantly, they’ll help you avoid anti-patterns with these new features that will cause your project to take longer, and have more quality issues.

Building LinqTo<Whatever>:  Understanding IQueryProvider

LINQ is powerful. LINQ is a great way to work with data, when your data source implements IQueryable. But, the only way you can use this powerful tool with custom data sources is to implement your own IQueryProvider. In this talk you’ll learn just what is necessary to build your own IQueryProvider that will enable developers to use the power of LINQ with your data source. We’ll build sample IQueryProviders for common datasources.

The first talk will show how many of the new features in the C# language and .NET 3.5 can be used in real world applications.  It answers a question I received from one local architect, "I don't even know when I recobnize a problem that LINQ can solve.".  It will show you the kinds of things LINQ will do for you in a real application, and how LINQ and the new language features integrate with the other parts of the .NET Framework you use every day.

The second talk is an in depth look at how you can build your own libraries to parse LINQ queries.  You'll learn the difference beteen IEnumerable<T> and IQueryable<T>. You'll learn when it's worth the work to create an IQueryable<T>, and just what that work entails.If you're building web services and you're providing your own client-side library for developers to use,you should learn these techniques. You may not always use them, but you should learn about them.

 And, the early bird deadline for Code Mash expires this coming Thursday (11/15).  Go register at www.codemash.org.

 

Posted by wwagner | with no comments

I received a question regarding my May column for Visual Studio Magazine. That column showed how you can use anonymous delegates to treat code as data.

The example wrote a series of delegates and methods that enabled XML serialization to files, memory streams, or compressed streams.  For example:

// Read from a compressed XML file:
public static T ReadCompressedXmlV1<T>(string pathName)
{
    return ReadFile<T>(pathName, delegate(Stream file)
    {
        return ReadCompressed<T>(file, delegate(Stream compressed)
        {
            return ReadXmlStream<T>(compressed);
        });
    });
}

// Write to a compressed XML file.
public static void SaveCompressedXmlV1<T>(T data, string pathName)
{
    WriteFile(pathName,
delegate(Stream s)
    {
        WriteCompressed(s,
delegate(Stream compressed)
        {
            WriteXmlStream(data, compressed);
        });
    });
}

A reader asked:

 Just a matter of curiosity – IMHO reading part with anonymous delegates became even MORE complicated with generics then “classic solution”.

I know it’s a tricky question but are any other way to reduce complexity for reading operations to avoid “Russian Dolls” scenario?

Well, C# 3.0 does give much better syntax for this. Here are the same methods written using lambda expressions, making use of the C# 3.0 language additions:

// Read from XML file:
public static T ReadCompressedXmlV2<T>(string pathName)
{
    return ReadFile<T>(pathName,
        file => ReadCompressed<T>(file,
            compressed => ReadXmlStream<T>(compressed))
    );
}

 // Write to an XML file:
public static void SaveCompressedXmlV2<T>(T data, string pathName)
{
    WriteFile(pathName,
        s => WriteCompressed(s,
            compressed => WriteXmlStream(data, compressed))
    );
}

The lambda expression syntax reads quite a bit more clear than the extra braces required for the classic C# syntax. It reflects the 'pipeline' nature of the algorithm.

What do you think?

Posted by wwagner | 2 comment(s)
Filed under: , ,

Steve blogs about it here: http://aspadvice.com/blogs/ssmith/archive/2007/11/02/Speaking-in-Ann-Arbor-November-14th.aspx.  He'll be up in Ann Arbor, discussing ASP.NET caching and performance.  I'm on a couple email lists with Steven and I know he's got a tremendous amount of information on the subject.  If you do anything with ASP.NET, this is a presentation you need to see.

Posted by wwagner | with no comments

Brian Grunkmeyer has written a rather deep article for the BCL weblog that discusses many of the pitfalls that surround finalization, dispose, and weird things that can happen during the birth, death, and possible resurrection of an object:

 http://blogs.msdn.com/bclteam/archive/2007/10/30/dispose-pattern-and-object-lifetime-brian-grunkemeyer.aspx

 Some of the important points he covers:

. What happens if an object's constructor thorws an exception?

. What happens if an object's finalizer is called as part of an AppDomain unloading?

. Why should I care?

. What can I do to prevent exceptions and application terminations?

Posted by wwagner | 1 comment(s)
Filed under: ,