Archive for January, 2010

MacBook Pro two year check-in

January 2010 – April 2011 Apple (, , ) • 6,672 views • 3 responses

It’s been an interesting couple of years with nothing but a maxed-out MacBook Pro 17″ as my only home machine.

Failures

The hard drive died but time machine held my hand. At ALT.NET Seattle 2009 my backpack took a dive that left a dent in one corner. The battery was replaced and I roped GrinGod into obtaining a replacement UK-style \ key from the UK after some frantic typing.

A friend cracked the display when his keyfob sprang from his Batbelt culminating in a visit of the Apple Store in Bellevue. Ten days and $700 later got that fixed and included a bonus disconnected thermal sensor, a couple of new scratches, an extra screw to rattle around inside and a line of grease around the Apple logo.

Sticking with it

When I find myself eying the unibody I wince at the glossy ‘matt finish’ screen, the multi-touch trackpad clicks that sound like Robocop is nearby and a US keyboard that requires my pinky to hit a single-height enter key. That little pink dog won’t learn any new tricks. I’ve tried.

Still the OpenCL benchmark show the 8600M outperforming the newer 9400M and it does everything I need and at least one thing I don’t (gets hot enough to bake bread on). Short of switching the hard disk out for an SSD – I’ve ordered twice and then recalled after a Twitter volley of “no, you don’t want THAT one” – it’s here to stay for at least another year.

Applications

One thing that is always changing is the bunch of installed applications as I search for a combination that deliver a nirvana between productivity and enjoyment. Apps that perform a set of focused useful tasks with a shiny, eminently lick-able user interface, score highly.

I’ve rounded up my favourite apps before but here’s the latest specials on the menu.

CleanMyMac

This great-looking app helps reclaim wasted space making it a pre-requisite for SSD switchers.

Combining the PowerPC and foreign language code-purging of XSlimmer & TrimTheFat is also adds cache & log purging in with application uninstalls ala AppZapper etc.

Despite using XSlimmer already on my machine it was able to reclaim another 1.8GB and V2 is out soon which I hope will remove & alias duplicates given we’re not getting ZFS which had this feature (how many copies of Sparkle.framework do I have on my machine….)

Coda

This year I rewrote my blog’s WordPress theme from scratch and given the PHP requirement I found myself looking for an alternate IDE to Visual Studio. I already own TextMate but the feel of a raw text editor with bundles of extra bits feel didn’t have the gloss and usability I wanted such as fast preview, remote FTP sync etc. with a minimal of setup fuss.

I briefly toyed with Espresso during the early development cycle but Coda won me over in the end with it’s sheer simplicity and elegance plus the addition of built-in documentation for PHP was very helpful when working offline.

BetterTouchTool

Yes, when the Magic Mouse hit the street I picked one up. The idea of a mouse with trackpad multi-touch technology was appealing but a few minutes of use and no amount of twiddling would make it track  or let me configure it to take full advantage of what it should be able to do.

Until Apple sort this out BetterTouchTool is your friend letting you speed up the tracking of the Magic Mouse, or indeed your trackpad, and assign all sorts of interesting shortcuts and abilities to combinations of finger gestures.

Secrets

Mac apps tend to expose only the common options in their user interfaces but sometimes developers add some additional tweaks and settings behind the scenes that live in the Mac’s equivalent of the registry (known as “defaults“). While you can set these manually using the defaults command-line tool you still need to know the setting exists, it’s name and what options are available and so secrets exposes this.

Secrets is similar to Deeper and TinkerTool but the difference is that the secrets web site lets people add new options which then are automatically available within the installed preferences pane making them easily discoverable, searchable, applied… and occasionally undone.

Machinarium

Screenshot of the game MachinariumThis point-and-click adventure game will appeal to people who enjoyed Monkey Island although it feels more like the gorgeously submerging Beneath a Steel Sky.

The scenery is brilliantly imagined, stylistic and shows that very real lived-in cities can be beautiful especially when populated by cute robots capable of assembling themselves from their own body-parts (just like a triple 8 but infinitely cuter).

[)amien

LINQ to SQL tips and tricks #3

January 2010 .NET () • 12,985 views • 4 responses

A few more interesting and lesser-known LINQ to SQL techniques.

Lazy loading with stored procedures

LINQ to SQL supports stored procedures for retrieving entities, insert, update and delete operations but you can also use them to perform lazy-loading of navigation properties.

Lets show an example of a bi-directional relationship between a Post and a Comment. We have two stored procedures shown below and we bring them into the DBML by dragging them from Server Explorer into the LINQ to SQL designer surface and we set the return type property for each to the expected entity (Post and Comment respectively).

CREATE PROCEDURE LoadPost (@PostID int) AS SELECT * FROM Posts WHERE ID = @PostID
CREATE PROCEDURE LoadComments(@PostID int) AS SELECT * FROM Comments WHERE Parent_Post_ID = @PostID

This generates two method stubs named LoadPost and LoadComments that we can use to programatically retrieve entities:

var post = dataContext.LoadPost(1).First();
Console.WriteLine("{0}", post.Title);

Now to replace LINQ to SQL’s lazy-loading query generation we add  methods to the data context subclass with a specific signature.

partial class DataClasses1DataContext {
    protected IEnumerable<Comment> LoadComments(Post post) {
        return this.LoadComments(post.ID);
    }

    protected Post LoadParentPost(Comment comment) {
        return this.LoadPost(comment.Post_ID).First();
    }
}

To get the signature of the method names right:

  1. Visibility can be anything (protected or private is recommended)
  2. Return type must be the type of the other side of the association (wrapped in IEnumerable<T> when that side can be many)
  3. Method name must start with the word “Load”
  4. Method name must then continue with the name of the navigation property you want to intercept
  5. Parameter type must be the type that has the named navigation property (step 4)

Storing and retrieving binary files

LINQ to SQL supports the SQL Server’s varbinary type but storing something practical like a file in there isn’t so clear. Map your varbinary(max) column from your table into your entity which will expose the column as the special System.Data.Linq.Binary type (effectively a wrapper for a byte array but better change tracking).

File to database

To store a file in the database just read those bytes in and assign them to the property (Binary knows how to create itself from a byte array automatically). e.g.

string readPath = @"c:\test.jpg";
var storedFile = new StoredFile();
storedFile.Binary = File.ReadAllBytes(readPath);
storedFile.FileName = Path.GetFileName(readPath);
data.StoredFiles.InsertOnSubmit(storedFile);

I recommend storing the file name as well as the binary contents for two reasons. Firstly writing the file back to disk or streaming it to a browser will require you know the file type (e.g. .jpg or image/jpeg) and secondly nobody likes downloading a a file called ‘download’ or ’1′ :)

Database to file

Writing the file back to disk is just as easy although you have to use the ToArray() method of System.Data.Linq.Binary to turn it back into a byte array.

string writePath = @"c:\temp";
var storedFile = data.StoredFiles.First();
File.WriteAllBytes(Path.Combine(writePath, storedFile.FileName), storedFile.Binary.ToArray());
Always ensure when writing to the file system based on data that your filenames are sanitized! You don’t want users overwriting important files on your system.

Multiple databases with a single context

Contrary to popular belief you can in fact access entities from multiple databases with a single data context providing they live on the same server. This isn’t supported but I’ve used it on my own projects without issue :)

The first part is the tricky bit which involves getting the definition of your entity into your DBML. You have two options here:

Create a temporary view

If you have the rights you can temporarily create views in your primary database for each table in your non-primary database.

CREATE VIEW MyOtherTable AS SELECT * FROM MyOtherDatabase.dbo.MyOtherTable

Once the views are created add them to your DBML by dragging them from Server Explorer into the LINQ to SQL designer surface and delete the views you created from the database.

Create a temporary DBML

If you can’t or don’t want to create temporary views then add a second (temporary) LINQ to SQL classes file (DBML) to your project. Use Server Explorer to find your secondary database and drag all the tables you will want to access to the LINQ to SQL designer surface.

Now save & close open files and use the right-mouse-button context menu to Open With… and choose XML Editor on your original DBML and the new temporary one. Head to the Window menu and select New Vertical Tab Group to make the next step easier.

Looking through the DBML you will see each entity has a <Table> block inside the <Database>. Select all the Table tags and their children (but not Database or Connection) and copy/paste them into your existing DBML file. Then close the files and check all looks well in the designer again.

If it does, delete the temporary DBML file you created. If not go back and check the DBML file for duplicate names, mismatched XML etc.

Finally, the easy bit

Open the designer and for each table that comes from the other database select it and change the Source property in the Properties window from dbo.MyOtherTable to MyOtherDatabase.dbo.MyOtherTable.

Hit play and run!

[)amien