Archive for June, 2009

Linq to SQL Quirks Part 3 – Extension to Get Around the Delete Problem

Tuesday, June 30th, 2009
This entry is part of a series, Linq to SQL Quirks»

My previous post about problems deleting can be partly handled with an extension method to the Linq to SQL Table(Of T) class with something like this…

         Public Sub DeleteOnSubmitOrDetach(Of T As Class)(ByVal table As System.Data.Linq.Table(Of T), ByVal o As T)
            Dim IDProperty = o.GetType.GetProperty("ID")
            If IDProperty Is Nothing Then
                Throw New System.MissingFieldException("Trying to delete object of type " & GetType(T).Name & " - does not have an ID field")
            End If
            If IDProperty.GetValue(o, New Object() {}) = 0 Then
            End If
        End Sub

Note that you’ll need to import System.ComponentModel and System.Reflection and possibly some others, and it assumes that you have an IDENTITY ID field by that name on all of your classes that you use this with.

Setting the .NET WebBrowser Control’s DocumentText Property

Tuesday, June 30th, 2009

The .NET framework comes with a nice WebBrowser control, which is a wrapper around MS Internet Explorer.  The problem is that it can be rather quirky at times, and one of these times is when you try to set the DocumentText property from code.  It might work, and then again it might not.  It is quite difficult to pin down exactly when it does work and when it doesn’t, but the following bit of code seems to set it for me…

  wbMsg.AllowNavigation = False
        wbMsg.AllowNavigation = True

        If wbMsg.Document Is Nothing Then
            wbMsg.DocumentText = s
        End If

Solid State Drives

Tuesday, June 30th, 2009

I just got my first SSD last week – a Crucial 32GB CT32GBFA0 if that means anything to anyone.  After rather a lot of experimentation, I discovered that it does seem to make a difference to the responsiveness of my system when I use it for swapfile space (better than ReadyBoost!  Not that I’m using Vista), but when I tried to replace my main partition with it for using it as my Windows drive, it was noticably slower than my main hard drive.  I’m not sure why this would be, since it is rated at a higher transfer rate, and it should have a much lower seek time, but I think it has something to do with the lack of onboard cache memory and inefficiency at processing multiple requests.  Well, hopefully they will get better in future.

With Slows Down Code?

Tuesday, June 30th, 2009

I just remembered something that happened a few years back in .NET 1.1 days (or maybe even it was .NET 1.0).

We were writing a rather complicated piece of code that needed to do lots of loops processing objects. Since it was taking an extremely long time, we ran it through a code profiler (a nice thing called ANTS Profiler – made by a company called Red Gate). One of the things that the profiler highlighted was that when we were using a With block to access a the return value of a function, every time the runtime used the With block to access the value, it was calling the function and taking extra time! This was a little surprising, as we had thought that With was dealt with at compile time, but apparently not. If my memory serves me correctly, I think that it was still slow when we assigned the return value of the function to a variable and used With to access that.

The basic upshot is that if you are in a situation where you are really bothered about speed, don’t use With to write code like that.

Windows 7 Release Date

Monday, June 29th, 2009

Apparently it is going to be out on the 22nd of October.  I’m looking forward!

Linq Part 3 – Query Format

Monday, June 29th, 2009
This entry is part of a series, Linq»

It is very easy when you are familiar with SQL to constrain yourself to treating Linq queries in a similar fashion and not take advantage of some of the new features that Linq allows. Of course, Linq does impose its own constraints, as does each Linq provider, so it isn’t always easier.

It is definitely worth getting your head around the fact that in Linq, you can query a query.  With some providers, this might mean that you are querying the results of a query, but with others, it can mean that you are simply building another query, which will only actually be executed when you try to retrieve the results.

For example,

Dim q = From p in DataContext.People Where p.Surname=”Smith”

q = From p in q Where p.FirstName=”John”

In Linq to SQL, this is perfectly efficient as it will only run SELECT * FROM Person WHERE Surname=’Smith’ AND FirstName=’John’ or something similar.

Equally, you can also combine multiple queries into a single statement, such as…

Dim q = From p in DataContext.People Select p.ID, p.Surname Order By p.Surname Select ID

…and of course you don’t need to worry about the order of the statements – notice a Select can come after an Order By!  The thing to remember is that each Select/Group effectively creates a different context (as in a variable context), so you have different variables available at each point in the query.

Generics in .NET Part 1 – What are Generics and How to Use Them

Monday, June 29th, 2009
This entry is part of a series, Generics»

One of the most important parts of program design is making sure that your code is as reusable and maintainable as possible.  Most major developments in new programming languages tend to be aimed towards this, as well as organisation of code.  The real problem is finding different ways of creating patterns of reusable code.

One of these ways is object orientation, including polymorphism.  Whilst this is very useful, it does have some limitations.  Sometimes it is useful to be able to create a data type or a method which is almost a template – it contains or operates on or is in other way based around some other type (or multiple types), which you want to pass in when you create it.  If you are a C++ programmer, you may be familiar with this concept as templates.

As an example, in .NET 1.0/1.1, you can create a Collection, but you can’t specify what type the objects in the collection are without creating a special class for each type that you want to include in a Collection.  In .NET 2.0, if you look in the System.Collections.Generic namespace, you will find a number of different collection types that use Generics to allow you to create a collection for a specific type of item.

For example, if you want a list of dates, you can create a List(Of Date).  This will create a list that not only forces you to only put dates into it, but also intellisense will be aware that an item contained within it will be a date and will be able to eg. use the AddDays method.

If you want to use a Generic class that takes multiple type parameters, you just pass them in using the format above Type(Of TemplateTypeName), only you use commas to separate them like Type(Of T1, T2, …).  An example of this would be if you wanted to create a Dictionary(Of Integer, String), which you could use to store a lookup table of integer numbers which each have a corresponding string.

Entries in this series:
  1. Generics in .NET Part 1 - What are Generics and How to Use Them
Powered by Hackadelic Sliding Notes 1.6.5

Linq Part 2 – From

Wednesday, June 24th, 2009
This entry is part of a series, Linq»

A Linq query will always start with From item in datasource

When I initially started using Linq, I thought that was a little odd, and why didn’t Microsoft just use SQL style Select columns from datasource.  I thought about this for a minute, and realised that the problem with that is that you can’t use Intellisense to get the column names because you don’t actually know what they are until you’ve specified the data source.

Another reason for this is that the Select part of a Linq query is not compulsory, so it makes more sense to start with the part that is.

You might find it a little confusing having to specify item if you are thinking in SQL terms, as you would usually just include a table name and possibly an alias in SQL.  The point in item is that a Linq query is a bit like a For loop in a single statement.  You are effectively looping around the items in the data source.  An individual provider might not actually implement it that way (Linq to SQL doesn’t – if you use a Where clause, it is translated to SQL instead of retrieving all the data and checking what matches), but that is the abstraction that we are using.  We don’t reference the item by using the datasource name because we might still want to access something else in the datasource separately in the query.

Linq to SQL Quirks Part 2: DeleteOnSubmit and Entity not Attached

Tuesday, June 23rd, 2009
This entry is part of a series, Linq to SQL Quirks»

If you use an implicit insert on a new object and then decide that you don’t actually want it, you have a bit of a problem.  First of all, you need to remove the relationships that you created so that it doesn’t show up in any places that it shouldn’t.  The problem with this is that Linq will still kind of (see below) have it marked for insertion, so if you call SubmitChanges without doing anything else, it will either still insert it, or if you’ve removed a relationship which relies on a non-nullable foreign key, you’ll get an error like

“An attempt was made to remove a relationship between a A and a B. However, one of the relationship’s foreign keys (A.BID) cannot be set to null.”

Where A and B are the 2 appropriate Linq to SQL classes.

The next thing we need to do then is to make sure that Linq to SQL removes the item from the insert list.  The only way that I have found to do this is to call DeleteOnSubmit on the appropriate table.  The problem is that if we do that at this point, we get an InvalidOperationException with message “Cannot remove an entity that has not been attached.”

Apparently, Linq to SQL knows it is supposed to insert it, but it isn’t properly attached.  To get around this, we need to call InsertOnSubmit on the appropriate table before calling DeleteOnSubmit.

That’s all fine and dandy and works, as long as you are trying to delete something that hasn’t been inserted yet.  Normally, however, I use the same code whether it has been inserted or not, and of course if you call InsertOnSubmit on an entity that has already been inserted, you get an InvalidOperationException saying “Cannot add an entity that already exists.”.  Therefore, before you call InsertOnSubmit, you need to check if it actually has already been inserted.  Since I always have identity fields with the name ID on all my tables and Linq to SQL updates these when it does an insert, I normally just check that the ID is 0 before inserting.

The resulting steps that you need to solve the problem are therefore: –

  1. Remove the relationships from item
  2. If the ID=0 then DataContext.Table.InsertOnSubmit(item)
  3. DataContext.Table.DeleteOnSubmit(item)

You shouldn’t actually have to call DataContext.SubmitChanges at this point – the whole point in the exercise is to mean it will be safe when you do later.

Alternatively, you can just throw away the datacontext without calling SubmitChanges, but I find that is rarely an option because there may be other data that needs submitting.

By the way, you need to do the first step of removing the relationships in order to make sure that none of your code accidentally tries to access the removed object as it will still be in memory as a related object until SubmitChanges is called otherwise and you could end up processing it when accessing entities related to an object that it is related to.

Google Wave

Tuesday, June 23rd, 2009

If you haven’t come across this yet and you’ve got a couple of hours to spare, take a look at it.  I can’t fairly describe what it does in a brief couple of paragraphs, so I’ll just say that I think that it will eventually replace email, IM, possibly a lot of word processing and collaborative working software.  Frankly it is very clever!