Microsoft has released a number of exciting new tools and technologies that certainly bear some watching! These are preview releases so the usual caveats apply about installing these on a production system.

The "home" page for Microsoft's Data Platform is here and it contains the most up to date information about the various shiny new pieces.

The main bits are ADO.NET Entity Framework Beta 3, ADO.NET Data Services CTP1, and ADO.NET Entity Framework Tools CTP2.

So what exactly is the Entity Framework? It's a toolset and framework that enables a developer to visually design and model data driven applications, both forms based and web based.

Collectively these technologies are part of the ASP.NET 3.5 Extensions which are in preview mode at the moment. Combined these technologies allow a developer to expose data from their applications in well known formats, some of which are not Microsoft specific such as JSON and REST and also in standards based formats such as XML.

There are a number of QuickStarts that the ASP.NET team has made available. Also as part of this release the ASP.NET MVC framework is available.

Go check it out!

 


 
Categories: .NET | ADO.NET | Ajax | ASP.NET | Programming | SQL | Visual Studio


At the office I was recently exposed to a tool called SQL Delta. Tools like this have been around for quite awhile, but this has to be the slickest and easiest to use interface I have seen.

The description of the tool from the products web page is:

"SQL Delta is a database compare and synchronization tool that performs both structure and data comparisons of SQL Server 2005, 2000 and 7 databases."

We use it here to sync up data and structure between the various build/test/uat/dev instances of our database back ends. It generates scripts, can run inside transactions, all the things you would expect. A little expensive for the home user but very affordable for a team.

Cheers,

Robert Porter


 
Categories: Programming | Reviews | SQL | Tools and Toys


Microsoft has release SQL Server 2005 SP2 as of yesterday February 19, 2007. The list of bug fixes contained in SP2 are detailed KB921896. The readme for the service pack is here, and the Service Pack download page is here.

Microsoft Virtual PC 2007 is a free download and is fully Vista compatible, as both a quest or host OS. I downloaded and installed it and it ran all my existing 2004 VM's with no problems, I did however update the Virtual Machine Extensions in all the existing VM's.

You can download Virtual PC 2007 here.

Happy downloading!

Robert Porter


 
Categories: SQL | Tools and Toys


I was recently using the old standby NorthWind database that has been a stock example database with SQL Server for a long time. It is no longer distributed with SQL Server 2005 but you can download updated scripts that will create and populate the database on SQL Server 2005. If you want them they can be downloaded here along with the companion pubs database as well. Don't let the title fool you, these scripts are 2005 aware even though the download page says 2000.

 

I have used the same or similar code to retrieve images stored in SQL server for a long while without issue but now I was getting errors retrieving the photo data.

Here is the code I was using:

 

        For Each row As DataGridViewRow In Me.dgvEmployees.SelectedRows

 

            Dim Emp As Employees = TryCast(row.DataBoundItem, Employees)

 

            If Not Emp Is Nothing Then

                Dim imageData() As Byte = CType(Emp.Photo, Byte())

                Dim msTemp As New MemoryStream

 

                msTemp.Write(imageData, 0, imageData.Length)

                Dim img As Image = Image.FromStream(msTemp)

                picEmployee.Image = img

            End If

 

            m_CurrentEmployeeID = CType(row.Cells(0).Value, Long)

            lblEmployeeID.Text = m_CurrentEmployeeID.ToString

 

        Next

The code was failing with an "Invalid Parameter" error on the line containing msTemp.Write

After some serious head scratching, and a little Google work I stumbled on this article on Visual Studio Magazines site. The article had a paragraph at the bottom that explained the mystery:

Notice a subtlety in this code that is particular of the Northwind database but has no relevance in general. The original Access database was converted into SQL Server's Northwind database, so the image field called Photo doesn't contain a true GIF file; instead it contains the OLE object that Access builds to wrap any image. As a result, the stream of bytes you read from the field is prefixed with a header you must strip off to get the bits of the image. Such a header is variable-length and also depends on the length of the originally imported file's name. For Northwind, the length of this offset is 78 bytes.

I changed my code to take that 78 byte header into account as follows and everything worked as it should have!

 

For Each row As DataGridViewRow In Me.dgvEmployees.SelectedRows

 

            Dim Emp As Employees = TryCast(row.DataBoundItem, Employees)

 

            If Not Emp Is Nothing Then

                Dim imageData() As Byte = CType(Emp.Photo, Byte())

                Dim msTemp As New MemoryStream

                'note the image data in Northwinds contains a 78 byte header

                'that needs to be stripped off.

                msTemp.Write(imageData, 78, imageData.Length - 78)

                Dim img As Image = Image.FromStream(msTemp)

                picEmployee.Image = img

            End If

 

            m_CurrentEmployeeID = CType(row.Cells(0).Value, Long)

            lblEmployeeID.Text = m_CurrentEmployeeID.ToString

 

        Next

Hopefully this will help the next person to stumble upon this historical oddity!

Cheers,

Robert Porter


 
Categories: Programming | SQL


In the last (and first) post of this series we discussed how to create a typed dataset. Now that we have our dataset we need to see how to use it.

But before we go into the details, I want to explain something that I stumbled upon in my research. There is a serious bug in the implementation of the dataset generator. It effects retrieving and manipulating childrows when you are dealing with related tables.

After a great deal of hair pulling, self doubt, and serious coffee consumption, I finally found a series of blog posts that ended up leading me here. The bug has been confirmed and will be released: “thanks again for reporting this. We fixed this problem and the fix will be available in the next Visual Studio release.”

Description
When you create a typed DataSet using the class-designer of VS.NET with a parent- and a child-table, a method is generated on the parentrow-class which should return the childrows. This method uses DataRow.GetChilds with the name of the relationship. This method returns a parentrow-array instead of a childrow-array. The generated method casts it to a childrow-array and thus causes a InvalidCastException.
This bug reduces some of the functionality of the typed dataset in production applications. There is a workaround, but it is a simple kludge, and the end result is that you cannot easily work with related data.
 
Ok, with that said, lets continue on with the series. Next post in this series will take us back into the thick of it. There is still a huge benefit to using typed datasets, just sad that this bug caused such an unfortunate loss of some of that functionality.
 
Cheers,
 
Robert Porter

 
Categories: .NET | ADO.NET | Programming | SQL | VB.NET | Visual Studio | XML


November 28, 2006
@ 11:11 PM

This post is my first attempt to share some of my own experience. Specifically with ADO.NET and Typed Datasets. Scott Guthrie published an excellent series of tutorials on creating a DAL using Typed Datasets.

This is not an attempt to duplicate that series, but it is inspired by it. And I also wanted to do this from a Winforms perspective rather than an ASP.NET view, since I still work in both worlds.

For my first effort, I created a fairly simple application that allows the user to perform simple, Select, Update, Delete and Insert operations against the SQL Server sample pubs database employee table.

SQL Server 2005 does not ship with the pubs or Northwind databases any longer. If you want the scripts to create them you can download them here. These scripts while designed for SQL Server 2000 worked just fine in SQL Server 2005 and created the databases and populated them with data. (They also include pre built databases in the form of MDF and LDF files that you can attach but I prefer to build them from the scripts.)

If you want to download the sample application that goes along with this series of tutorial posts you can do so here. File Attachment: MasterDetail001.zip (71 KB)

I am going to begin this series in earnest tomorrow with the first of the “meat” posts. And let me clearly state, the code in the sample app is very basic, little or no error handling, and not necessarily even the correct way of doing things. I am looking for constructive feedback myself. This application, as it grows, and the tutorials that accompany it are as much a learning exercise for me as anything else.

Cheers,

Bob Porter


 
Categories: .NET | ADO.NET | Programming | SQL | VB.NET | Visual Studio | XML


I recently ran into an issue where I needed to change the local instance of SQL Server 2005 from the Standard Edition to the Developer Edition. This was so I could install the latest version of Team Edition for Database Professionals which is currently at the CTP7 release. You can download it here. More about this fantastic new tool in a later post.

The tool requires either the Developer or Enterprise editions of SQL Server. And I had Standard Edition installed. I felt slightly ill at the prospect of uninstalling SQL Server and re-installing the Developer Edition, re-importing all my databases and the rest of the overhead involved. Surely there must be a better way! And there is!

Note: Microsoft has a great KB that helps you determine your SQL Server version and edition here so if you are unsure what version and edition you have check this article out for how to determine for yourself. For my version (2005) I ran the following query: SELECT  SERVERPROPERTY('productversion'), SERVERPROPERTY ('productlevel'), SERVERPROPERTY ('edition')

It turns out that you can indeed “Upgrade” from one SQL Server Edition to another via the foresight and magic of the SKUUPGRADE command line parameter. I inserted the Developer Edition CD, opened an command prompt and typed the following command line in:

start /wait setup.exe ADDLOCAL=SQL_Engine INSTANCENAME=MSSQLSERVER UPGRADE=SQL_Engine SKUUPGRADE=1 /qb

You can replace the /qb with /qn if you want a silent upgrade but then you will need to check the install logs for any errors. Of course it should go without saying that you need to backup all your databases first.

One other note, according to the MSDN library instructions for this parameter: If you use the SKUUPGRADE parameter, Setup will remove all hotfix and service pack updates from the SQL Server instance being upgraded. Once the edition upgrade is complete, you must re-apply all hotfix and service pack updates.

And last note, the command as written will upgrade the default local instance of SQL Server, if you are working with a remote instance or a named or otherwise non-default instance you will need to do some spelunking in the help files. A great place to start is here which is an MSDN article on How to install SQL Server 2005 from a command line.

Your mileage may vary but my own experience was uneventful and successful. I re-applied SP1 and then the post SP1 cumulative hotfixes and I was up and running! My previously installed Standard Edition now reports that it is indeed a Developer Edition install.

Final warning, if you are using Team Foundation server and the SQL Server you are about to work with is also used to host the Team Foundation Server schema changing it to Developer edition will break Team Foundation Server which will not run on the Developer Edition. Be sure before you change the edition of you server that you think through any other cross dependencies before you pull that trigger!

Cheers,

Robert Porter

 


 
Categories: SQL | Visual Studio


There are literally dozens of articles on how to retrieve images from a database and display them in a web page.  The vast majority use one of two variations.

Variation 1

Retrieve the image data, save it to a temporary file and then use the file as the image controls ImageURL or src.

Variation 2

Use an .aspx page with its content type set to an image/xyz type and retrieve the image within the ‘loader’ page and use that page as the image controls ImageURL or src.

I can’t use Variation 1 because I don’t want to create temporary files for a variety or reasons. Variation 2 works for individual images but I need to be able to quickly pull back up to 12 images and I experienced problems using this method within a loop from the calling page.

So here comes Variation 3. I am still not 100% satisfied by this but it works. As an aside since I can retrieve the image as a byte array directly from the database I would love to be able to do something like:

PageLoad Event

Go get image from DB and return it as either a Byte Array or a memorystream

Image1.ImageURL.LoadFromStream(ms)

Alas even though I wish it to be true it does not appear to be possible. However in the Wrox Book “ASP.NET 2.0 MVP Hacks and Tips” I stumbled on what turned out to be my solution in chapter 17 the part titled “Compositing Images with an HttpHandler” which was written by Scott Hanselman

So my solution was a variation on Variation 2, I created a HttpHandler class that in essence does the same thing, it retrieves the image data and then writes the image directly to the output stream and so I can now call my handler and pass in some parameters like this:

Using the html img tag:

<img src="GetImages.ashx?RecID=90&Size=Small">

Or using the server side model:

Image1.ImageUrl = "~/GetImages.ashx?RecID=90&Size=Model"

This method works like a champ even in a loop, and seems to be much faster than the .aspx page method. Not sure why, perhaps an HttpHandler does not have the overhead a full .aspx page does, but it sure works well.

The full code for my solution is below: Note: this was test code, I would NOT recommend using dynamic SQL like I do below in a production application, instead use parameterized sql.

<%@ WebHandler Language="VB" Class="GetImages" %>

    1 Imports System

    2 Imports System.Web

    3 Imports System.IO

    4 Imports System.Drawing

    5 Imports System.Drawing.Imaging

    6 

    7 Public Class GetImages : Implements IHttpHandler

    8 

    9     Public Sub ProcessRequest(ByVal ctx As HttpContext) Implements IHttpHandler.ProcessRequest

   10         'Create the request object and retrieve the QueryString Parameters

   11         Dim req As HttpRequest = ctx.Request

   12         Dim iRecID As Integer = CType(req.QueryString("RecID"), Integer)

   13         Dim sPicSize As String = CType(req.QueryString("Size"), String)

   14         Dim img() As Byte = GetData(iRecID, sPicSize)

   15         ctx.Response.ContentType = "image/gif"

   16 

   17         If (Not (img) Is Nothing) Then

   18             Dim m As MemoryStream = New MemoryStream(img)

   19             Dim image As Image = System.Drawing.Image.FromStream(m)

   20             image.Save(ctx.Response.OutputStream, ImageFormat.Gif)

   21         End If

   22 

   23     End Sub

   24 

   25     Public Function GetData(ByVal iRecID As Integer, ByVal sPicSize As String) As Byte()

   26 

   27         Dim cnn As Data.SqlClient.SqlConnection

   28         Dim cmd As Data.SqlClient.SqlCommand

   29         Dim msTemp As New MemoryStream

   30         Dim strSQL As String

   31 

   32         Select Case sPicSize

   33             Case "Large"

   34                 strSQL = "SELECT LargeImage FROM cyb_Frames WHERE RecID=" & iRecID

   35             Case "Small"

   36                 strSQL = "SELECT Thumbnail FROM cyb_Frames WHERE RecID=" & iRecID

   37             Case "Model"

   38                 strSQL = "SELECT ImageWithModel FROM cyb_Frames WHERE RecID=" & iRecID

   39             Case Else

   40                 strSQL = "SELECT LargeImage FROM cyb_Frames WHERE RecID=" & iRecID

   41         End Select

   42 

   43         Dim connString As String = Web.Configuration.WebConfigurationManager.ConnectionStrings("xyz").ConnectionString

   44         cnn = New Data.SqlClient.SqlConnection(connString)

   45         cmd = New Data.SqlClient.SqlCommand(strSQL, cnn)

   46         cnn.Open()

   47 

   48         Return cmd.ExecuteScalar

   49 

   50     End Function

   51 

   52     Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable

   53         Get

   54             Return False

   55         End Get

   56     End Property

   57 

   58 End Class


 
Categories: .NET | ASP.NET | SQL | VB.NET


 have learned to really dislike SQL Servers IDENTITY feature. (Those of us more familiar with Oracle, think of an IDENTITY column as a Sequence built into a table.)

In a hurry I tossed in dozens of IDENTITY columns, used em as FK’s all over as well, and then had to re populate a table….  Oh oh, now I remember why you don’t use IDENTITY with impunity!

Sigh…..

Back to the drawing (design) board. Being sloppy because I was in a hurry is no excuse, but now we get to pay the piper. (Must be a rich SOB by now!)

-Robert Porter


 
Categories: Misc | Repost from Blogger | SQL


January 2, 2005
@ 12:41 AM

Hmmm