Get updates on a site that has no RSS-Feed

I just came across a site that looks awful but has a very nice feature. It's just small, just like this article, but I thought this tool is so handy, everybody should know about it. It notifies a user that a specific site has been updated. The basic usage is through e-mail but it's also possible to make use of your personal RSS-Feed. Take a look at it yourself. ChangeDetection.com.

Linq to SQL doing it manually: Part 2 - Database creation

This week I started a series on Linq to SQL doing it manually. The serie contains of the following parts:

This part I'll introduce the actual creation of the database, tables and columns. The people that already have made use of Linq to SQL through the dbml-designer, know the generation of a class that inherits from DataContext. The DataContext class contains an method called CreateDatabase.

But the documentation mentions the algorithm that's used:

DataContext.CreateDatabase Method

  • If a database is identified in the connection string, its name is used.
  • If a DatabaseAttribute attribute is present, its Name property is used as the name of the database.
  • If there is no database tag in the connection string and a strongly typed DataContext is used, a database that has the same name as the DataContext inheriting class is checked.
  • If a weakly typed DataContext is used, an exception is thrown.
  • If the DataContext has been created by using a file name, the database corresponding to that file name is created.

I just tried something out to get to know more about it. What I first did, was create a mapping for a few classes so that tables for those classes could be created. I also created a database where I wanted to get generated tables.

So my first approach was the following:

  1. Instantiate a DataContext class with a connection-string.
  2. Call CreateDatabase method.

1 var context = new DataContext(@"..."); 2 context.CreateDatabase();

What happened was an exception. Just according to the algorithm in the documentation. Although the exception message was somewhat strange: "Unable to create database because data context 'DataContext' has no tables." I think this is kind of a strange message, but the documentation already mentions this wasn't going to work.

My second approach.

  1. Create a class derived from DataContext.
  2. Instantiate the derived class with a connection-string.
  3. Call CreateDatabase method on the derived class.
1 public class EmptyContext : DataContext 2 { 3 public EmptyContext(string fileOrServerOrConnection) 4 : base(fileOrServerOrConnection) 5 { 6 } 7 }

var context = new EmptyContext(@"..."); context.CreateDatabase();

Still no luck, I got an exception again. The message was the same though: "Unable to create database because data context 'DataContext' has no tables." This got me thinking. The Context needs to know about the mapped classes in some way. So I took a look at the context that's generated by the designer.

I found get properties for each table/class that was mapped.

My third approach, let's add some properties.

  1. Create a class derived from DataContext.
  2. Add properties of Table<mappedClassType> to the DataContext.
  3. Call CreateDatabase method on the derived class.

1 public class Context : DataContext 2 { 3 public Context(string fileOrServerOrConnection) : base(fileOrServerOrConnection) 4 { 5 } 6 7 8 public Table<Tag> Tags 9 { 10 get { return GetTable<Tag>(); } 11 } 12 13 public Table<Post> Posts 14 { 15 get { return GetTable<Post>(); } 16 } 17 18 public Table<PostTagRelation> PostTagRelations 19 { 20 get { return GetTable<PostTagRelation>(); } 21 } 22 }

1 var context = new Context(@"..."); 2 context.CreateDatabase();

Very nice, this solution almost created the database. I got an error that the database already existed, so I deleted it, and tried again. Succes!

Book review: Silverlight 2 in Action now in print

It's already a year ago when I read the first piece of Silverlight in Action. At that time it was still called Silverlight 1.1. But now Silverlight 2 In Action by Chad A. Campbell and John Stockton is in print.

I really like this book, it helped me learn Silverlight, so I recommend this book to everyone into learning Silverlight 2.

It covers all the stuff you need to know about Silverlight, including:

  • Interaction with the old web
  • Layout and text
  • User interaction
  • Data binding
  • Networking and communications
  • Digital media
  • Graphics and transforms
  • Animation
  • Styling
  • Distribution and deployment

Linq to SQL doing it manually: Part 1 - Table and column creation from C#

I was very interesting in doing Linq to SQL manually. Yes manually, not making use of the dbml-designer. And why should I want to do this? I thought it would be interesting to do Linq to SQL without a database being available yet.

I've also heard the rumor that Linq to SQL is dead, or almost dead. I'm not sure about this, but I still think Linq to SQL can be appropriate for simple situations, where Linq to Entities is for the more advanced scenario's it's also more complex to apply.

Attribute-Based mapping

What I need is Attribute-Based mapping I guess. The documentation talks about 9 different attributes:

  • DatabaseAttribute
  • TableAttribute
  • ColumnAttribute
  • AssociationAttribute
  • InheritanceMappingAttribute
  • FunctionAttribute
  • ParameterAttribute
  • ResultTypeAttribute
  • DataAttribute

In part 1, I will concentrate on the TableAttribute and the ColumnAttribute.

The TableAttribute

The TableAttribute makes sure a class gets mapped to a database table. As we have no table yet, we want to have as less code as possible. The following code makes sure a class gets mapped to a table. The class Tag gets mapped to the table named Tag.

[Table] public class Tag {}

Sometimes you want to have some control on the naming of the table. This is possible by just applying the Name property. This is just as simple as the following code. The class Tag gets mapped to the table named Tags.

[Table(Name="Tags")] public class Tag {}

This is all I have to say about the TableAttribute.

The ColumnAttribute

The ColumnAttribute is a little more advanced than the TableAttribute. But it can also be as simple as the TableAttribute. This is because all the primitive types are automatically mapped to a database type. But where do we start? Just very simple just add the ColumnAttribute to a property. The property Name gets mapped to the database column named Name.

[Column] public string Name { get; set; }

If you want the Name property to be mapped to the database column CustomerName we can do the following.

[Column(Name="CustomerName")] public string Name { get; set; }

It's possible to have some influence on the type that's used in the database for a column. I think this can be handy sometimes. For example if you want the Name field to be maximized to 25 characters and also not nullable, you can use this.

[Column(DbType="NVarChar(25) NOT NULL")] public string Name { get; set; }

But I like the feature that Linq to SQL does the mapping himself. The following diagram is derived from MSDN and shows what mappings are possible.

Mapping for SQL and CLR Types

The default mapping for the CLR types are the following:

CLR Type Default SQL Type
System.Enum INT
System.Boolean BIT
System.Byte TINYINT
System.Int16 SMALLINT
System.Int32 INT
System.Int64 BIGINT
System.SByte SMALLINT
System.UInt16 INT
System.UInt32 BIGINT
System.UInt64 DECIMAL (20)
System.Decimal DECIMAL (29,4)
System.Single REAL
System.Double FLOAT
System.Char NCHAR(1)
System.String NVARCHAR(4000)
System.Char[] NVARCHAR(4000)
Custom type implementing Parse() and ToString() NVARCHAR(MAX)
System.DateTime DATETIME
System.DateTimeOffset DATETIMEOFFSET
System.TimeSpan TIME
System.Date.Linq.Binary VARBINARY(MAX)
System.Byte VARBINARY(MAX)
System.Runtime.Serialization.ISerializable VARBINARY(MAX)
System.Guid UNIQUEIDENTIFIER
System.Object SQL_VARIANT

We also want some columns to be identifying. This can be done by setting the IsPrimaryKey property that's part of the ColumnAttribute. The following example makes the property Id the primary key. It's possible to have multiple properties to define a composed primary key.

[Table] public class Tag { [Column(IsPrimaryKey = true)] public Guid Id { get; set; } [Column] public string Name { get; set; } }

Next article will be about the actual generation of the tables and columns from the class definition.