Saturday, February 02, 2008

Burlington geeks from the itty bitty little market that can get 120 peope to who up at an MSDN event :-), will have to plan a road trip if they want to attend an official Launch event for VS2008, SQL SErver 2008 and Windows 2008 Server. There will be one in Boston on March 18 and one in Albany on May 23.

However, we will have two INETA/Microsoft/PASS sponsored launch events through the VTdotNET and VTSQL. VTSQL will have a "SQL Sever 2008 launch party" meeting on April 7th and VTdotNET's VS2008 Launch will be on April 14th. While we can't promise a copy of all three products to every attendee, hopefully we'll have licenses to give away. Fortunately, in December we were extremely lucky to have a VS2008 Install Fest where over 40 licenses to VS2008 Pro were given away to Vermont.NET User Group members, thanks to Chris Bowen.

Saturday, February 02, 2008 2:03:02 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

At VTdotNET's last meeting, we were happy to have Jeff McWherter share with us his hard-earned lessons about improving performance in asp.net apps. Jeff spends a lot of time dealing with this in his job and it was very obvious that he wasn't just sharing something he read about, but his very adept experience.

He started out by posing what may seem a redundant question, but is a really good way of getting people to focus on the issues. He asked for someone to explain the difference between web site performance and web site scalability.

These were the two topics he focused on as he delved into a number of performance bottlenecks as well as issues which prevent websites from being able to scale out. Jeff used a variety of performance measurement tools in the process which was very educational. Sure beats waiting for the server to come to it's knees as an indication that some changes might need to be made! Then of course he showed us lots of ways, some very simple, some more complex, to solve the problems displayed by the tools.

Often people focus on their specific asp.net code and don't consider out of scope processes that may be causing the problems such as a database query or a file download. I was happy that he made sure people were aware of SQLProfiler!

One of the tips that really hit home for me, because I was dealing with this problem, was if you have file download/upload functions in your application, split those off to another process, whether you can do that on another server or just in another app on your web server (e.g a web service). It's not just the time involved (which can be helped also by doing this asynchronously) but the resources involved. If multiple people are uploading or downloading at the same time, this could really pose a problem.

In these days where many of us are scrambling to learn the new technologies that are coming down the pipe, it is a huge benefit to have someone show us how to get more out of the tools that we are working with today with lessons that will apply to the tools of the future.

The day after the meeting, Jeff and his wife (who had spent a fun few days with us at our house) headed off to Smuggler's Notch to do some ice climbing and then were going to be on vacation for a while after that visiting friends around the Northeast.

I think he's back in Michigan now, so I'll be sure to get his list of resources from him and up on the VTdotNET site.

Saturday, February 02, 2008 9:25:02 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [2]  | 
 Friday, February 01, 2008

I change my mind daily about going to MIX.

I WANT TO GO TO MIX. The registrations are dwindling and it will soon be sold out.

But I don't want to deal with this:

SOUTH BURLINGTON -- Today's ice storm has caused numerous delays and cancellations this afternoon at Burlington International Airport, airport officials said.

Between about 3 and 5 p.m., there are expected to have been two delayed and two canceled arrivals, and another four or five delays and two canceled departures from the airport, said airport Facilities Manager Brian Searles.

"Right now, it's really all about where flights are coming from," said Searles. "We're operational here."

Searles said a continuing ice-build up could force the airport to close at some point this evening.

People should call the the airlines for more information on their flight, Searles said.

[source today's burlington free press]

This article doesn't even mention the winds that have been howling the past 6 hours. It's not much fun to be in a plane that is landing in high winds on ice covered runways. Been there done that.

And then there's always the fun at O'Hare. Last April we sat onthe runway for 2 hours when we landed at O'Hare, got on another plane and sat there for 3 hours before we took off. Bah!

Friday, February 01, 2008 9:56:02 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [1]  | 

In my post about rewriting Brad Abram's MVC + Entity Framework example in VB, I pointed out a better way to query a collection of objects and return their entity references (eg, query products and bring along the category information) without writing a scary query filled with references, checks for nulls, etc.

But there was something bothering me about the query.

I went from this (Brad's)

List<Product> products =TheProducts.Where(c => c.Category.CategoryName == category).ToList();
//prepare the view by explicitly loading the categories  
products.FindAll(p => p.Category == null).ForEach(p => p.CategoryReference.Load()); 

To this

     var _prod = Northwind.Categories.
              Where(c => c.CategoryName == id).
              OrderBy(c => c.CategoryName).
              Select(c => c.Products).
              First().ToList();

Which gives the same effect of ending up with a set of products and being able to drill into product.category.categoryname, etc.

But that query represents something that Entity Framework is not supposed to do, and I asked Danny Simmons about it.

Entity Framework will not perform actions that you did not request. I selected only products in my projection, yet I also got back categories. It was convenient, but it was against the promise of EF. I didn't ask for categories.

In the end, a bug was filed, because indeed, that shouldn't be happening.

However, it's still VERY easy to explicitly tell EF to bring along a collection (eg if I query categories I can say "and give me those products while your at it) or an entity ref (query products and ask for the category) by using Include.

Here's the same query for the MVC view even simpler.

    var _products = Northwind.Products.Include("Category").
        Where(p => p.Category.CategoryID == 1).ToList();

There are other ways to achieve this as well, but for this scenario, this is the most streamlined (as far as I know ;-)).
Friday, February 01, 2008 9:08:15 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [4]  | 

The date's been picked for the next New England Code Camp!

More details to come - watch Chris Bowen's blog!

Friday, February 01, 2008 8:05:22 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
 Thursday, January 31, 2008

I followed the great walkthrough on Brad's blog showing how to use MVC together with Entity Framework. But I did it my own way - in VB, using a different database and trying to write more effective EF queries. I have a simple solution that renders these views from the AdventureWorksLT database:

Start with a list of customers who have orders in the system (that's less than 10% of the full customer list)

Then I can click on a customer and see a list of their orders

 

Then drill in to see the order details. (The Edit button is not implemented yet, in case you were wondering!)

 

So here is what's significantly different from Brad's walkthrough.

  • My EDM is created from AdventureWorksLT.
  • The relationship from AW's SalesOrderHeaders to Customer is the same as the relationship from Northwind's Products to Category. Therefore, where he use Products, I use SalesOrderHeaders and  where he uses Categories, I use Customers.
  • One of the keys for getting data easily to a view is that we need to send ONE object (and not an anoymous type) to the view. Yet what we really desire in the case of the List of Order (which also has the Customer Name) and the list of details (which also has data from the order and the customer) is an object graph.

So on the 2nd page, I need to pass in an set of orders with their related Customer entity so that I can have access to the customer name.

On the 3rd page, I need to pass in a set of order details with their related Order entiteis AND the order's related customer.

Brad achieves this by starting with the desired entity and then using entity references and some scary looking LINQ to Entities queries.

List<Product> products =TheProducts.Where(c => c.Category.CategoryName == category).ToList();
//prepare the view by explicitly loading the categories  
products.FindAll(p => p.Category == null).ForEach(p => p.CategoryReference.Load()); 

Only because I've spent a lot of time with LINQ to Entities, do I happen to know a little trick.

If I start with the "parent", i.e. category and query it's property collection (i.e. products), when I return the property collection, the "parent" entity is still attached.

So taking Brad's query, I can get the same effect with this query (still in C#):

     var _prod = Northwind.Categories.
              Where(c => c.CategoryName == id).
              OrderBy(c => c.CategoryName).
              Select(c => c.Products).
              First().ToList(); 

(Update: turns out this only works because of a bug which will get fixed - see THIS POST for an even better way!)

This returns a list of products that belong to the category. However I do not have to do any extra loading to get to Product.Category.CategoryName. Beasue my query began with the Category, it's already there. (I learned this by trial and error by the way.)

Therefore, in my SalesOrderController (my versoin of his productController), the List ControllerAction code is a little different.

I use the same type of querying to get the order details.

Another thing that I spent some time thinking about and asking about was about the ObjectContext. In a web app you want an ojbectcontext to be as short-lived as possible. I notice that Brad was instantiating in the class level declarations. This is okay because in the background, MVC  instantiates  the class for each ControllerAction and then disposes it when it's finished. It doesn't hang around waiting for another method call. (This is one of the key premises of MVC. As Kevin Hoffman explained to me, it works in "short bursts" long enough to get something out to the browser. I have much to learn!)

Brad uses the CategoryName as the basis for the view creation so that he gets a pretty URL http://host/products/list/Beverages.

I'm still seeing if there is a way around this, but I don't like querying on a string like this. I like my keys! So I'm passing in CustomerID and SalesOrderID and my urls aren't as pretty.

Here is what my controller looks like and you can see my queries that populate the Customer List, the customer's order list and the order's detail list.

Imports System.Web.Mvc
Imports System.Linq
Imports MvcApplication.awModel
Namespace MvcApplication.Controllers 

  Public Class SalesOrdersController
    Inherits System.Web.Mvc.Controller
    <ControllerAction()> _
    Sub Index()
      REM Add Action Logic here
    End Sub
    'example URL:http://localhost:xxxx/SalesOrders/Customers
    <ControllerAction()> _
    Public Sub Customers()
      Using aw = New awEntities
        Dim _customers = aw.Customers. _
Where(Function(c) c.SalesOrderHeaders.Any). _
OrderBy(Function(c) c.CompanyName).ToList RenderView("Customers", _customers) End Using End Sub
    'example URL:http://localhost:xxxx/SalesOrders/List/[CustomerID]
    <ControllerAction()> _
    Public Sub List(ByVal id As String)
      Using aw = New awEntities
        Dim _salesorders = (From cust In aw.Customers _
                          Where cust.CustomerID = id _
                          Select cust.SalesOrderHeaders).FirstorDefault.ToList
        RenderView("SalesOrdersbyCustomer", _salesorders)
      End Using
    End Sub
    'example URL:http://localhost:xxxx/SalesOrders/List/#### (order number)
    <ControllerAction()> _
    Public Sub Detail(ByVal id As String)
      Using aw = New awEntities
        Dim _order = (From ord In aw.SalesOrderHeaders.Include("SalesOrderDetails.Product") _
                     Where ord.SalesOrderID = id _
                     Select ord).First
        Dim _order2 = (From cust In aw.Customers.Include("SalesOrderHeaders.SalesOrderDetails.Product") _
                   Where cust.SalesOrderHeaders.Any(Function(so As SalesOrderHeader) so.SalesOrderID = id) _
                   Select cust.SalesOrderHeaders).First.ToList.First
        RenderView("SalesOrder", _order2)
      End Using
    End Sub 

  End Class
End Namespace 

The markup is not really different from Brad's since I can drill from the ViewData into my references (Customer, Product, SalesOrder) thanks to my queries (which make me feel so clever!)

The last page just uses tables to do the trick.

<asp:Content ID="Content1" ContentPlaceHolderID="MainContentPlaceHolder" runat="server">
<h2><%=ViewData.Customer.CompanyName%></h2>
<h3>
<%=String.Format("Sales Order #: {0}", ViewData.SalesOrderNumber)%>
<%=String.Format("Order Date: {0:d}", ViewData.OrderDate)%>
<%=String.Format("Order Total: {0:C2}", ViewData.TotalDue)%>
</h3>
 <table>
 <tr><td style="width: 225px">Product</td><td style="width: 154px">Quantity</td>
   <td style="width: 256px">Line Item Total</td></tr>
            <% For Each detail As awModel.SalesOrderDetail In ViewData.SalesOrderDetails%>
            <tr>
               <td style="width: 225px"><%=detail.Product.Name%></td>  
               <td align="center" style="width: 154px"><%=detail.OrderQty%></td>
               <td style="width: 256px"> <%=String.Format("{0:C2}", detail.LineTotal)%></td>
            </tr>
        <% Next%>
    </table>
</asp:Content>

As an aside, this was my first time really playing with client side code in VS2008 and I am enamored of all the intellisense in there!

Thursday, January 31, 2008 3:03:52 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [2]  | 

In the TabletPC SDKs and in WPF it's very easy to take an ink image and save it to an image format - BMP, JPG, etc.

Then came Silverlight and the InkPresenter and naturally I wanted to do the same. But it wasn't so easy.

Silverlight itself isn't bogged down with that functionality. So you first need to get the XAML representation of the Ink and send it to a service where either the TabletPC SDK or the WPF APIs are available. Even then you are not home free because the Silverlight ink is not quite the same as either of the other two. So you then need to extract data from the XAML representation of the Silverlight ink and create a new object for whichever API you choose.

This was all done in Silverlight 1.0. I haven't pulled this into Silverlight 1.1/2.0 yet, but it should all be the same and you still have to do the conversion on the server side. THe only difference of course, is the javascript needs to be converted to .NET code on the client side.

Even then, there is still some more trickery because there is something strange with using the width from the Silverlight object and I spent hours just experimenting with getting the proportions to display properly in the image. I also spent a lot of time struggling with the colors because the javascript output of the color values doesn't line up with what WPF wants. You'll see in the code comments all of the conversions going on.

Once I had all of that worked out (and this represents hours of effort) there were still some issues. Luckily, Stefan Wick, who is the ultimate guru on this topic and finally has a blog - hoorah!, was able to set me straight (and trim some  of my code down significantly).

I hadn't thought much of this nor, apparently had anyone else, until someone recently emailed asking me how I did it so that he can use it as part of a solution in a competition. (I hope that the requirements of the competition don't say anything about original work!), so I thought I would blog the steps.

1) Convert the InkPresenter data to XAML . This does two things. FIrst it enables you to serialize it and pass it to a web service and secondly, it is the lowest reasonable common denominator for sharing between different objects. This javascript code comes from Gavin Gear.

This javascript code reads through the StrokeCollection property of an InkPresenter and builds up a string of xml that is the XAML representation of the StrokeCollection. You could also take the resulting string and pass it to CreateFromXAML to recreate the Silverlight StrokeCollection object.

  if (strokeCollection.Count>0)
  { 
   var xaml = "<StrokeCollection>";
   if (strokeCollection != null)
   {
    for (var i = 0; i < strokeCollection.Count; i++)
    {
        var stroke = strokeCollection.GetItem(i);
        if (stroke.Name>"")
          xaml += "<Stroke Name='" + stroke.Name + "'><Stroke.DrawingAttributes>";
        else
          xaml += "<Stroke><Stroke.DrawingAttributes>";
        xaml += "<DrawingAttributes ";
        xaml += "Color='" + BrowserColorConverter(stroke.DrawingAttributes.Color) + "' ";
        xaml += "OutlineColor='" + convertColorToHexString(stroke.DrawingAttributes.OutlineColor) + "' ";
        xaml += "Width='" + stroke.DrawingAttributes.Width + "' ";
        xaml += "Height='" + stroke.DrawingAttributes.Height + "' ";
        xaml += "/></Stroke.DrawingAttributes>";
        xaml += "<Stroke.StylusPoints>";
        for (var j = 0; j < stroke.StylusPoints.Count; j++)
        {
            var stylusPoint = stroke.StylusPoints.GetItem(j);
            xaml += "<StylusPoint X='" + roundToTwoDecimalPlaces(stylusPoint.X) + "' Y='" +
roundToTwoDecimalPlaces(stylusPoint.Y) + "' />"; } xaml += "</Stroke.StylusPoints></Stroke>"; } } xaml += "</StrokeCollection>";

 

2) Pass this string to a web service method that will do the following to it

3) Create a WPF InkObject from the XAML. Now that I'm in the web service, I can use .NET code. Phew. Note that I did this before I knew how to use LINQ to XML so I struggled through XPath to get this. Watch for an upcoming MSDN Mag article that will have updated code.

      private static StrokeCollection InkObjectfromXAML(XmlNode StrokeColl)
      {
          StrokeCollection objStrokes = new StrokeCollection();
          XmlNodeList strokeElements =
          StrokeColl.SelectNodes("Stroke");
          foreach (XmlNode strokeNodeElement in strokeElements)
          { 

              //step 1: create a new stroke from the stylus point elements in the XAML
              XmlNodeList stylusPointElements =
                  strokeNodeElement.SelectNodes("./Stroke.StylusPoints/StylusPoint");
              XmlNode drawAttribs = strokeNodeElement.SelectSingleNode("./Stroke.DrawingAttributes");
              //points node is sent to GetStrokePOints method to convert to a type 
//that can be used by the new stroke
System.Windows.Input.StylusPointCollection strokeData = GetStrokePoints(stylusPointElements); Stroke newstroke = new Stroke(strokeData); //step 2: grab color metadata about stroke from the xaml //color is a hex value //the stroke object requires a System.Windows.Media.Color type //following code performs the conversion string mycolor = drawAttribs.FirstChild.Attributes["Color"].Value; System.Drawing.Color drwColor = System.Drawing.ColorTranslator.FromHtml(mycolor); //build the new color from the a,r,g,b values of the drawing.color System.Windows.Media.Color newColor = new System.Windows.Media.Color(); newColor.A = drwColor.A; newColor.R = drwColor.R; newColor.G = drwColor.G; newColor.B = drwColor.B; //Step 3: extract width data from xaml, convert to int int myIntWidth; bool parseSuccess = int.TryParse(drawAttribs.FirstChild.Attributes["Width"].Value,
out myIntWidth); //Step 4: apply width & color to stroke //some really wierd unexplainable transformations that I had to get
              // around until the final images looked right.
if (myIntWidth == 3) newstroke.DrawingAttributes.Width = 1.5; else newstroke.DrawingAttributes.Width = 2; newstroke.DrawingAttributes.Color = newColor; //Step 5: add stroke to the stroke collection objStrokes.Add(newstroke); } return objStrokes; }
    //This method (called from the method above, is an abstraciton of some sample code from Microsoft
     private static System.Windows.Input.StylusPointCollection GetStrokePoints(XmlNodeList stylusPointElements)
        {
System.Windows.Input.StylusPointCollection pointData = new System.Windows.Input.StylusPointCollection();

            //The object requires HiMetric point values, create multiplier for conversion
            double pixelToHimetricMultiplier = (2540d / 96d) / 100;

            foreach (XmlNode stylusPointElement in stylusPointElements)
            {
                string xStr = stylusPointElement.Attributes["X"].Value;
                string yStr = stylusPointElement.Attributes["Y"].Value;

                //x and y are in pixels, we need to multiply them to get them into HIMETRIC
                //space, which is what the InkAnalyzerBase expects
                int xInHimetric = (int)(System.Convert.ToDouble(xStr) * pixelToHimetricMultiplier);
                int yInHimetric = (int)(System.Convert.ToDouble(yStr) * pixelToHimetricMultiplier);
                pointData.Add(new System.Windows.Input.StylusPoint(xInHimetric, yInHimetric));
            }

            return pointData;
        }
Now we have an inkObject that WPF will be happy with!

4) Convert WPF Ink to PNG format bytes This is with a BIG thanks to Stefan - we need to start a separate thread to do the conversion from WPF Ink ojbect to PNG. That conversion happens inside the thread. Also, thank to his deep understanding of the ink object, Stefan was able to accomplish in a much smaller amount of code what I had achieved in about 3 times as much code. I was definitely doing loop-dee-loops, but it was the best I could come up at the time.

Note that I am not saving to an actual file here, just creating the bytes because my goal was to store that in a database.

   private static void ThreadforConverttoPNG()
   {
    Thread t = new Thread(new ThreadStart(ConverttoPNG));
    t.SetApartmentState(ApartmentState.STA);  

    // Start ThreadProc.  Note that on a uniprocessor, the new 
    // thread does not get any processor time until the main thread 
    // is preempted or yields.  Uncomment the Thread.Sleep that 
    // follows t.Start() to see the difference.
    t.Start();
   }
   private static void ConverttoPNG()
   {
    //I had originally achieved this with a LOT more code. This is Stefan's more trimmed down method

    //create temporary InkCanvas
    InkCanvas inkCanvas = new InkCanvas();
    inkCanvas.Strokes = strokes;
    //render InkCanvas to a RenderBitmapTarget
    Rect rect = inkCanvas.Strokes.GetBounds();
    RenderTargetBitmap rtb = new RenderTargetBitmap((int)rect.Right, 
(int)rect.Bottom, 96d, 96d, System.Windows.Media.PixelFormats.Default); rtb.Render(inkCanvas); //endcode as PNG BitmapEncoder pngEncoder = new PngBitmapEncoder(); pngEncoder.Frames.Add(BitmapFrame.Create(rtb)); //save to memory stream System.IO.MemoryStream ms = new System.IO.MemoryStream(); pngEncoder.Save(ms); ms.Close(); strokeBytes= ms.ToArray();    }

5) My next step was actually to store the bytes into a database. I wasn't actually saving out to a file. But to do that is simple. System.IO.File lets you create a new file on the fly from a byte array.

   System.IO.File.WriteAllBytes("C:\\myfile.png",strokeBytes); 

So, those are all of the pieces from converting a silverlight inkpresenter image to an image file.

Thursday, January 31, 2008 10:06:29 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
 Wednesday, January 30, 2008

Jonathan Bruce is the .NET wizard at DataDirect, who makes a variety of data providers for .NET.

Among his Predictions for 2008 in this blog post, he includes these four regarding .NET:

1. Data Services changes becomes universal programming model.

2. IBM files a draws together a set of established JDBC experts to establish LINQ for Java, Java Specification Request (JSR)

3. Dynamic LINQ bridges gap between compile-time type checking available in more static LINQ constructs.

4. LINQ to SQL will be forced to open up their lighter weight model to third-party provider-writers.

The last is especially of interest as I muse about whether 3rd party providers will be writing LINQ providers AND EF providers, or just write EF providers and get the LINQ part for free, even though it may mean a little more effort to developers who want to do the more RAD development offered by LINQ to SQL.

While DataDirect is definitely working on EF providers (Oracle, SyBase, SQL Server and DB2). It certainly sounds like DataDirect is interested in writing direct LINQ providers.

Wednesday, January 30, 2008 7:13:00 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
 Tuesday, January 29, 2008

Oh now I am really excited. I've been very interested in ASP.NET MVC but have been trying to stay focused on learning Entity Framework.

Now I get to have my cake and eat it too, as Brad Abrams just posted a sample of using the two together.

I'm off to try it out!

Tuesday, January 29, 2008 4:27:49 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [1]  | 

And they all seemed pretty surprised that there were so many cool creative and tech companies in Vermont who were looking for employees!

I saw on Cairn Cross' blog  (he works for a local VC) that the folks at the entrance of Satruday's Vermont 3.0 event "stopped counting after 1,000"!

Eva Sollberger made an incredible video of the day. Check it out!

Tuesday, January 29, 2008 1:08:19 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

QVAULT in Burlington has an opening for an .Net Developer. "We are looking for more of an Entry Level to Associate Level person, but are willing to see and consider a more experienced person if they are a good match."

Skills Required

ASP.NET, C#, Web Services

Job Description

If you are an experienced ASP.NET developer, or a soon to be or recent graduate of a programming oriented curriculum, who wants to work for a great Vermont Owned company, read on!

Qvault is looking for a talented software developer who prefers a fast paced and diverse environment, an individual who is a creative self-starter and desires to be an integral part of a team building a young company.

Required skills:

- Understanding of ASP.NET
- C#
- Web Services

Desirable skills:

- AJAX
- XML
- JavaScript
- SQL Fundamentals (MS SQL platform, management tools, jobs)
- SQL Stored Procedures
- HTML/XHTML
- Web standards and cross-browser/platform delivery
- ColdFusion
- IIS6

About Qvault:

Qvault, Inc., a privately held corporation; develops, hosts and supports web based business intelligence, collaboration and document/content management solutions for professional organizations throughout North America.  Please visit our website at www.Qvault.com.  Qvault's main offices are located in downtown Burlington, Vermont.

Tuesday, January 29, 2008 10:42:28 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

A great resource from the WPF SDK Blog

WPF Basic Data Binding FAQ

Tuesday, January 29, 2008 9:59:10 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

There's a big difference between looking for a problem to solve with LINQ vs realizing LINQ will solve the problem at hand. Patrik Lowendahl had his "aha!" moment recently. Read more....

[A New DevLife Post]

Tuesday, January 29, 2008 9:26:25 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

I have been waiting for this information for quite some time! Read more...

[A New DevLife Post]

Tuesday, January 29, 2008 8:46:19 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

Yes, it's true. Right here in Burlington. Apparently it got a little "out of control".

Tuesday, January 29, 2008 8:10:21 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
 Monday, January 28, 2008

Mike Pizzo from the Data Programmability team is doing a webcast on Wednesday.

MSDN Webcast: Programming LINQ and the ADO.NET Entity Framework (Level 200) 
Event ID: 1032364888
      Register Online 
 
Language(s):  English. 
Product(s):  SQL Server. 
Audience(s):  Developer. 
 
Duration:  60 Minutes 
Start Date:  Wednesday, January 30, 2008 11:00 AM Pacific Time (US & Canada) 

Event Overview

Language Integrated Query (LINQ) introduces an exciting new way for applications to build strongly typed queries that are deeply integrated into the programming language. The ADO.NET Entity Framework allows applications and services to work in terms of an application-oriented Entity Data Model, decoupling the application's data model from the storage considerations of the relational schema. Join this webcast to see how these two technologies work together to change the way applications work with data.

Presenter: Michael Pizzo, Principal Architect, Microsoft Corporation

Michael Pizzo is a principal architect on the Data Programmability Team at Microsoft. He has been at the forefront of data access for the last 17 of his 20 years at Microsoft, including contributing to Open Database Connectivity (ODBC), Object Linking and Embedding Database (OLEDB), ADO, ADO.NET and now the Entity Framework. Michael has been a member of the ANSI X3H2 Database Standards Group and a U.S. representative in the International Standards Organization (ISO) meeting that approved the SQLCLI as an extension to SQL92.

View other sessions from: SQL Server 2008: Develop Strong Database Applications

If you have questions or feedback, contact us.

Monday, January 28, 2008 6:38:54 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

I thought I would give the Xceed WPF DataGrid (it's free!) a whirl with Entity Framework databinding. So far I have only explored the basics - no anonymous types or sprocs and I am only working with a READ-ONLY scenario. (I did notice something in their docs about being able to modify and delete but not add when binding to LINQ to SQL queries.) I have, however, at least used a multi-level object graph.

Here's what I've come up with.

Add the grid

  1. Drop an Xceed WPF DataGrid on a WPF Window

Preparing the data

  1. I created an EDM from AdventureWOrksLT. The namespace is awModel and the EntityContainer is awEntities. I also fixed up some naming, plurazing the EntitySets and the navigation properties that point to collections. (This is my standard routine when creating EDMs)
  2. In the Loaded event for the WIndow, add the following
Dim aw = New awModel.awEntities
Me.DataGridControl1.ItemsSource = From ord In aw.SalesOrderHeaders.Include("Customer") _
Select ord

Setting up the grid for Databinding

If you've never used WPF, or done databinding in WPF, there are definitely a lot of new things to learn! The easiest thing to do for now is just copy and paste all of this XAML below.

Here's what the entire XAML looks like.

<Window x:Class="Window2"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window2" Height="300" Width="300" Name="Window1" xmlns:xcdg="http://schemas.xceed.com/wpf/xaml/datagrid"
        xmlns:local="clr-namespace:WpfApplication1.awModel">
    <Grid>
    <Grid.Resources>
      <DataTemplate DataType="{x:Type local:SalesOrderHeader}">
        <TextBlock Text="{Binding TotalDue}"/>
      </DataTemplate>

      <DataTemplate DataType="{x:Type local:Customer}">
        <TextBlock Text="{Binding Customer.CompanyName}"/>
      </DataTemplate>

    </Grid.Resources>

    <xcdg:DataGridControl Margin="10,9,4,0" Name="DataGridControl1" ItemsSource="{Binding}" >
      <xcdg:DataGridControl.Columns>

        <xcdg:Column FieldName="Customer.CompanyName" Title="Company" />
        <xcdg:Column FieldName="TotalDue" Title="Total Due"/>
      </xcdg:DataGridControl.Columns>

    </xcdg:DataGridControl>

  </Grid>
</Window>

The xml namespace tag xdcg get's added automatically when you drop the DataGrid on the window.

The xml namespace tag "local" is something I added. It's necessary for subsequent references to classes from my EDM. Intellisense will help you pick the right namespace (your app and your model name) if you start with clr-namespace:.

In my query, I queried for SalesOrderHeaders plus their customer EntityRefs. In the DataTemplates, you can see that I'm referencing the actual object model types and then binding to the property from the SalesOrderHeader that is returned in my query.  "TotalDue" gets me "SalesOrderHeader.TotalDue" and "Customer.CompanyName" gets me "SalesOrderHeader.Customer.CompanyName". The DataTemplate provides binding to the data source (defined in the ItemsSource setting in the code above). Then the DataGrid column tie back to the bindings by way of the FieldName property.

Run the app

Note that I did not sort in my query.  I wanted to demonstrate the grid's built in sorting , but for some reason it's not working in this scenario (stay tuned...I'll get to the bottom of that).

The automatic grouping does work, though. AdventureWorksLT is not great for seeing this. Only Thrifty Parts and Sales happens to have more than one order.

Monday, January 28, 2008 2:12:26 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [7]  | 

I spent a lot of time playing (and just attempting to play) with the new CR2008. Both what's included out of the box with Visual Studio 2008 and their standalone application. There were a lot of surprises. I wrote an article about everything I learned about things like backwards compatiblitiy, integration into different versions of Visual STudio, etc. It's here on ASPAlliance: What Visual Studio Developers Should Know About Crystal Reports 2008

Monday, January 28, 2008 1:32:00 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
 Sunday, January 27, 2008

A question came up in the EF forums today asking if the delay of SQL Server 2008's release will mean EF will be delayed.

The two are not related.

There is a misconception that Entity Framework is tied to SQL Server 2008. It's definitely not. These are .NET APIs and will work with many database providers (when those providers are written).

As far as I know, the official word on EF's release remains "1st half of 2008". Something tells me that won't be any time in January. ;-)

Sunday, January 27, 2008 8:13:47 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

Yesterday I did a fun session at the Vermont 3.0 event titled: "Software Developer: Career or Addiction?".

I've had a bad chest cold for 2 weeks and yesterday was actually better day for me than these past weeks.

I took all I could to prevent coughing.

The talks were all being recorded by the local public access channel.

Apparently, according to DanZ (who was standing near the area where the video feed was being monitoried) what coughing I did do (and I don't recall caughing UP anything, as gross as he makes it sound - eeeew) sounded seriously nasty over the mic. I'm definitely not looking forward to hearing that.

Throughout the day, every time I met someone who wanted to shake hands I had to tell them "oh, no, you do NOT want to touch me". I even passed up shaking hands with Sen. Bernie Sanders. I didn't want to be responsible for passing this cruddy cold onto him! (or anyone)

And Dan, thanks for not stealing my car! ;-)

Sunday, January 27, 2008 6:21:04 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  |