In this post we’ll see how using CodeFluent Entities’ SQL Server Template Producer, you can generate SQL scripts using the built-in template engine whilst accessing the inferred meta-model, and then automatically deploy the generated script on your desired server.
By default SQL Azure and SQL Server add the clustered index on the primary key if a clustered index on the table does not already exist and if you do not specify a unique nonclustered index. In the case where the primary key is of GUID type it won’t be efficient. The reason for this is that GUIDs are generated in non-sequential order and SQL Server orders a clustered index sequentially. It will work – SQL Server will let you build a clustered index around a unique identifier column, however it will cause the SQL Server to do unnecessary work and cause performance slowdowns.
That being said, what we can do is using the SQL Template Producer to remove all inefficient clustered indexes and recreate them on the right columns. Let’s even go a bit further and create a little aspect that will add a property on each property to tell if a clustered index needs to be created or not on that particular property.
Add a new Part called IsClusteredIndexAspect and past it the following code (replacing the defaultNamespace’s value by yours):
<cf:project xmlns:cf=”http://www.softfluent.com/codefluent/2005/1” defaultNamespace=”yourNamespace”>
<cf:pattern name=”IsClusteredIndex Aspect” namespaceUri=”http://www.sample.com/aspects/isclusteredindexaspect/2012/11” preferredPrefix=”sa” step=”Tables”>
<cf:message class=”_doc”>
This aspect creates an extra IsClusteredIndex bool property on every property.
</cf:message><cf:descriptor name=”IsClusteredIndex” typeName=”boolean” targets=”Property” defaultValue=”false” displayName=”IsClusteredIndex” description=”Should the IsClusteredIndex Aspect apply to this property?” />
</cf:pattern>
</cf:project>
This will create our aspect and add a IsClusteredIndex property on each property in the “Aspects and Producers” property grid:
Image may be NSFW.
Clik here to view.
You can by now choose which property you want to use as a clustered index. Obviously this property should be set to true only on one property by entity since clustered index cannot be applied on several columns.
Now let’s write a script that will remove all clustered indexes and then create new ones based on the columns selected thanks to our aspect. In a file called “[Template]CreateIndexes.sql” add it the following code (Note that this code is only an illustration for this post, it does not take into account constraints, primary keys and so on):
[%@ namespace name="CodeFluent.Model"%] [%@ namespace name="CodeFluent.Model.Persistence"%] [%@ namespace name="CodeFluent.Producers.SqlServer"%] /* [%=Producer.GetSignature()%] */ [%foreach (Entity e in Producer.Project.Entities) {%] --remove any existing clustered index on e.Table.FullName --[...] [%foreach (Property p in e.Properties) { if (p.GetAttributeValue("sa:IsClusteredIndex", false)) {%] --create your index such as: CREATE CLUSTERED INDEX [CL_[%=p.Entity.Table.Name%]] ON [%=p.Entity.Table.FullName%] ([[%=p.Column.Name%]]); GO [%} } }%]
Create a folder called “Template” under the file folder of your CodeFluent Entities project:
Image may be NSFW.
Clik here to view.
Right click on that folder and choose “Add existing item” then browse to your template file and select it.
Now in your CodeFluent Entities project, add an instance of the SQL Server Template Producer with your Template directory as the “Source Directory” and set the “Target Directory” to the project of you choice and then build over your model. The SQL Server Template Producer will generate a script file from your template, and run the script on the server removing and creating clustered indexes. Therefore using the template producer you can quickly create complex scripts by taking advantage of the meta model.
Cheers,
Thibault NESTOR
Image may be NSFW.
Clik here to view.
Clik here to view.
