When looking at developing new applications I always end up developing my own data layer. Largely because I do not like the dictatorial design principles spouted by the likes of ActiveRecord, nHibernate, et al. I write them according to real life situations where database design isn't as clean as it perhaps should be and there is no opportunity to make key changes, etc. And you know what, rolling your own is so much easier and much less hassle.
For my current project, though, I thought I'd try something "new" ...
I have been looking at Telerik's new OpenAccess ORM application recently. Telerik acquired the software a while back and have introduced it into their excellent value Premium RadControls product suite. The Express version is a good way to investigate if it is for you, so long as you are using it on a "free" database server such as SQLExpress, SQLLite, etc.
I thought I'd jot down some quick lessons I have learnt along the way.
Templates
My coding style does not match Telerik's code style as generated from the OpenAccess Reverse Engineering option. Whereas Telerik's generated form of a private member is in the format:
private string siteName;
My preferred style is:
private string _siteName;
There are few things more frustrating than adopting someone elses coding style, so I set about investigating how to get around this.
There are a number of templates that define how the classes are built when you Reverse Engineer, which are stored in the C:\Program Files\Telerik\OpenAccess ORM\sdk\IDEIntegrations\templates\PCClassGeneration folder (or your equivalent).
To change the private member format, you need to open all the files and look for a reference to the "$fieldName" variable. I changed this to "_$fieldName" and it generated the correct code.
It did not, however, generate the correct mappings, which are stored in the reversemapping.config and App.config files, which I had to tweak manually. I still have a forum post outstanding on this one.
Deferred Execution
If you get an "IObjectScope is closed" exception, you'll probably be doing something intelligent like creating a nice Factory Design Pattern, whereby you get your object within the IObjectScope and return it out for use by your BIZ objects. OpenAccess execution is deferred, however, which means if you access any of the properties outside of the IObjectScope context, you get the exception. So, for my factory method that Gets a Site object:
public object Get(Guid id)
{
Site site = null;
using (IObjectScope scope = Database.Get(_session.ConnectionId).GetObjectScope())
{
scope.Transaction.Begin();
using (IQueryResult result = scope.GetOqlQuery("SELECT * FROM SiteExtent").Execute())
{
if (result.Count > 0) site = (Site) result[0];
string s=site.SiteName;
}
scope.Transaction.Commit();
}
return site;
}
Note that I access the site.SiteName property and discard it. This just forces OpenAccess to perform the Get and put the Site object into memory so when I drop out of the method, I don't lose the object.
Using LINQ
Telerik say their Open Access solution is a mid point between LINQ to SQL and Entity Framework. Seems good to me, but there are a few gotchas you need to know about.
As with anything in the OpenAccess ORM (unless you are working with SQL directly), you don't work with tables, you work with Extents. The non-LINQ way of doing things int he code sample above shows the OQL query "SELECT * FROM SectionExtent". The table name is Section, but OpenAccess maps it into an Extent. The same model works when using LINQ. Before you can start using Extents in LINQ, you need to add the Telerik.OpenAccess.Query namespace.
If you're using of the Telerik products, you might want to follow @telerikbuzz on Twitter for useful information and updates.
Here's another pet hate in web bad-practice: Javascript. Javascript is a client-side scripting language that allows really useful interaction to occur with the page and the browser, thereby improving the end user experience when using a site. It's very easy to insert Javascript in a page, not so easy to do it right.
I despair when I look at many people's sites, blogs and networks due to JavaScript errors. It really spoils the experience for me. If I follow a link to a site with the promise of interesting content, I do not want to be presented with a series of JavaScript errors in order to get to that content. I'll just leave. Over the past couple of weeks, (since 1st December to be exact), I have been collecting some of the sites that have JavaScript errors on them (in Internet Explroer 7):

JavaScript errors can occur due to a number of problems, which bloggers/webmasters aren't always bothered about. From the most basic blog with a Twitter feed to advanced sites such as Facebook, the result of a Javascript error is the same: unwanted behaviour often accompanied by error messages that mean nothing to the end user.
There are a number of excellent resources for getting JavaScript snippets to add to your own site, many of them contributed to by "real" Javascript programmers more capable of handling Javascript code than me. Unfortunately, however, differing scripting dialects and runtimes mean that sometimes these scripts haven't been thoroughly tested on all browsers.
The increase in social networking, "widgets" and advertising services such as Google Adwords results in external Javascript being injected into the page in order to facilitate a particular requirement. For example, on the home page of my site is a Twitter script that gets my Twitter status from Twitter and injects it into the Document Object Model (DOM) of my home page. It's really neat. But if Twitter fails (as it regularly does) or the JavaScript doesn't work with my browser for whatever reason, I will get a JavaScript error - and it will be beyond my control. If possible, it's a good idea to pull the scripts off the remote servers and host them locally so you can react better in the case of an error.
As JavaScript essentially runs in accordance with the page load cycle, it requires that the programmer has made resources available in the right place and in the right order for scripts to run flawlessly. If the page load is disrupted somehow, then errors may be caused which could remove functionality from the page. For example, if I load invoke a script in the HEAD of a page, which relies on a control in the BODY, the control would not be rendered when the script executes, thereby generating an error. A simple error, but one which is often forgotten about particularly as network speeds get faster. It becomes easier to assume the user's page loads as fast as yours. If a script resource gets "held back" over the network for whatever reason, preceding scripts could easily fail.
There is a definite trend to making the web browser work more like a desktop application with every new web application released. Google is particularly focused on the RIA (Rich Internet Application) which uses techniques such as AJAX to create the impression of a responsive and fully functional application within the web browser. Unfortunately, the script behind these applications is bound to be very complex and errors easily creep in. Take Google Reader, it doesn't work on my copy of IE7. Take GMail, it regularly fails on IE7. The complexity of the applications is no excuse. Windows is a complex product but users will (rightly) criticise it and damn the product when it fails to work. The same should go for web sites that use faulty JavaScript. Users of Sitecore will know the powerful Content Editing environment that runs using extensive Javascript - it works fine. The only time I get JavaScript errors are when I cause them by fiddling with my browsing context (eg. Internet -> Intranet zones), etc.
I can almost hear the cries, "use Firefox 3.1" and "use Google Chrome", due to their JavaScript optimisation. Why should I? I use a browser that is easy to access and is on every machine I touch - that is IE 7, which occupies the majority of the browser market. If you write an web/JavaScript application, it should work on ALL browsers, within reason.
By "All Browsers", I mean:
- Internet Explorer 7
- Internet Explorer 6
- Firefox 2
- Firefox 3
- Safari
- Google Chrome
You'll notice that I have not included beta versions of browsers (although I do test my work on these when I believe it is relevant - ie. close to release) and I have gone back a version for the two main browsers, Internet Explorer and Firefox. If your Javascript doesn't work in all these browsers, or degrade gracefully, you really shouldn't release the code.
The JavaScript error message is a jarring experience and spoils many a site. The most attractive site can be ruined by a JavaScript error or two. Just because your browser places a little yellow triangle on the status bar indicating an error has occured in the page, doesn't mean other users have adopted the same configuration. The average user, who has stumbled on a page with a scrpt error, would not understand why certain aspects of the page are unresponsive as a result of any errors that have occured.
My view on JavaScript best practice is: not to use it. If you have to use it, make sure it is error checked and gracefully degrades functionality if required. Also, make sure that alternative functionality is available if the functionality it provides is important to the use of the site. I would struggle to find any reason for JavaScript to be on any "front-end" site, whether it is a blog, corporate site or e-Commerce outlet. Javascript should be a complement to a well designed site, which should add value to the user experience. Tickers, counters, advertisements, etc. are not essential to the content on a page.
There are few things more satisfying in using a web page than when a subtle visual cue is provided to indicate an action has been actioned. Facebook has a number of scripts that allow you to click on text to edit it and then apply it, for example, when updating your status. It's all happening client-side, with minimal AJAX. It works really well - when JavaScript is available and the script works. If for whatever reason JavaScript isn't available (maybe the browsing platform doesn't support it), there is the alternative of typing it in (in most cases) and clicking 'Post'.
Also, remember that search engines will ignore JavaScript. As I always say, your biggest user is deaf, dumb and blind, and that is the search engine. You have to treat the search engine as if it is a base-level browser as a first step of Search Engine Optimisation (SEO), then adding on additional optimisations both for SEO and user experience, which means JavaScript gets added last and does not prevent loading of the page by search engines. I have seen sites that load the next page in the navigation sequence using JavaScript and while it is all very clever in technique, it is not clever in practice. The search bots are getting cleverer all the time and there are rumours of automated JavaScript execution engines that attempt to mimic a user, but these cannot be gauranteed and therefore you should not wrap content only within JavaScript.
If I can, I always look for tried and tested components, rather then develop my own Javascript. I know my limitations, and Javascript isn't a strong point. But when I need it, I'll make sure it works, or look for a component I know will work and will have support behind it. That is why I use Telerik's RadControls for ASP.NET AJAX for situations where I need complex client-side functionality, possibly to create an RIA experience. I can pay for the components, know that the testing has already been done and assuming I do my work right, should just be able to "drop in" the components and tweak accordingly.
If you are working with JavaScript, good practice is to turn on JavaScript errors in your browser. That way, no matter what rush there is to launch a site, a script error will always be important - because it will directly annoy you everytime it happens. I turn on script debugging and error messages as part of my web work as standard, and it pays off in my site quality.
Update (23 December 2008):
This has been a popular post, and I'd like to thank Jim Connolly for his feedback. After reading this post, he checked the page about Advertising on his site and all seems well now. It's good to see that we share the same views on web site quality, as he was very prompt about addressing the issue and contacting me about it.
I'll keep this list up to date and will name and shame sites that fail to trap JavaScript issues. I encourage you to do the same, if you find a site you're struggling to use, feel free to leave a comment and I'll add it to my list.