A Look at JamesCMS: Code First Development

Posted Sunday, March 10, 2013 in Old JamesCMS Posts

When developing JamesCMS I used Entity Framework 5 and a principle called Code First Development. This allows me to write my data classes before developing a SQL database. In fact using this method allows for the SQL database to be created at runtime and supports several SQL providers. Changes to the database structure is managed through Code First Migrations which essentially puts my database structure into source control.

Adding Indexing Functionality to Entity Framework

One of the things that I've added is index and full text index attributes based off this post. Entity Framework more or less stays unaware of the SQL architecture being used so some features such as indexes aren't handled when creating a new database. Well I still want the performance benifits of indexes but want to stay with a purely Code First Development. To do so I created the IndexInitializer and FullTextIndexInitializer. Both are wrapped into a single InitializeDatabase call using the CompositeDatabaseInitializer. Both of these initializers look for data annotation attributes in the model. So for example, the IndexAttribute is defined as such:

{{C#}}
[AttributeUsage(AttributeTargets.Property, 
	Inherited = false, AllowMultiple = true)]
public class IndexAttribute : Attribute
{
    public IndexAttribute(string name, 
    	bool unique = false, 
    	bool descending = false)
    {
        this.Name = name;
        this.IsUnique = unique;
        this.Descending = descending;
    }

    public string Name { get; private set; }

    public bool IsUnique { get; private set; }

    public bool Descending { get; private set; }
}

And later referenced in the data model like so:

{{C#}}
[Table("Texts")]
[FullTextIndex("FTIX_Texts", "Title, Article")]
public class Text : Entity
{
    ...snip...
    [Required]
    [Index("IX_Text_Posted", false, true)]
    public DateTime Posted { get; set; }
    ...snip...        
}

As you can see I also have a reference to the full text index initializer which is set at the table level. For the full text indexing I've also set the ability for it to be disabled in the event that full text indexing isn't enabled at the SQL server. At Application_Start my customized database initializer is set:

{{C#}}
if (FullTextEnabled)
{
  Database.SetInitializer<TextContext>(
    new CompositeDatabaseInitializer<TextContext>(
      new IndexInitializer<TextContext>(),
      new FullTextIndexInitializer<TextContext>()
    )
  );
}
else
{
    Database.SetInitializer<TextContext>(
        new IndexInitializer<TextContext>()
    );
}