CoNatural Components v1.6

Roger Torres - March 26th, 2010

You can find the latest CoNatural Components (v1.6) Here.

This version is mainly an upgrade to the Visual Studio AddIn, incorporating many new features like asynchronous wizards and support for T4 templates.

If you are planning to use T4 to generate your CRUD commands and/or Model types from SQL tables, I’m providing basic templates, but you can modify them to fit your requirements. For example, if you use a datetime field named “ModifiedDate” in your tables to record the last time a record was modified, you can use the following T4 template:

Update.tt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
<#@ template language="C#v3.5" HostSpecific="True" #>
<#
	CrudHost host = (CrudHost)Host;
#>
//-------------------------------------------------------
// CoNatural.Data Visual Studio AddIn T4 Template Engine
//-- <#= host.Name #>.cs
//--
//-- Created by <#= Environment.UserName #> 
//-- Created on <#= DateTime.Now #>
//-------------------------------------------------------
 
using System;
using System.Data;
using CoNatural.Data;
 
namespace <#= host.Namespace #> {
	public class <#= host.Name #> : ICommand {
		public <#= host.Name #>() {}
 
		public string GetScript() {
			return 
@"UPDATE
	[<#= host.Schema #>].[<#= host.Table #>]
SET
<#
int a = 0;
for(int i = 0; i < host.Columns.Length; i++) {
	if (host.InPrimaryKey[i]) continue;
	if (host.Columns[i] == "ModifiedDate") {
#>
	<#= a++ > 0 ? ", " : "  " #>[<#= host.Columns[i] #>] = getdate()
<#
	}
	else {
#>
	<#= a++ > 0 ? ", " : "  " #>[<#= host.Columns[i] #>] = @<#= host.Properties[i] #>
<#
	}
}
#>
WHERE
<#
int b = 0;
for(int i = 0; i < host.Columns.Length; i++) {
	if (host.InPrimaryKey[i] || host.Columns[i] == "ModifiedDate") {
#>
	<#= b++ > 0 ? "AND " : "    " #>[<#= host.Columns[i] #>] = @<#= host.Properties[i] #>
<#
	}
}
#>
 
IF @@ROWCOUNT = 0
	RAISERROR(N'Update failed. Check if original record was modified by another user.', 16, 1)
"; 
		}
 
<#  
for(int i = 0; i < host.Columns.Length; i++) {
#>
		<#= host.PropertyAttributes[i] #>public <#= host.PropertyTypes[i] #> <#= host.Properties[i] #> { get; set; }
<#
}
#>
	}
}

The SQL statement will raise an error if the ModifiedDate field doesn’t match, which means someone else changed the record. This is a very basic example, but you get the idea right?

All the T4 templates must be located under the {Project Root}/T4 folder as shown below:

Project with T4 templates

Project with T4 templates

Just make sure you remove the “Custom Tool” option when adding .tt template files to your project.

The AddIn provides a custom text templating host to process CoNatural templates. The templates are identified by name (Insert.tt, Select.tt, SelectAll.tt, Update.tt, Delete.tt, and Model.tt).

If you are planning to modify a template, you must cast the Host property to the type CrudHost (this is our custom host).

This type provides many properties you can use to build your logic:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
using System;
using System.Data;
using System.Collections.Generic;
using Microsoft.SqlServer.Management.Smo;
using CoNatural.Data.VisualStudio.AddIn.Helpers;
 
namespace CoNatural.Data.VisualStudio.AddIn.Tools {
	[Serializable]
	public class CrudHost : TextTemplatingEngineHostBase {
		public string Schema { get; private set; }
		public string Table { get; private set; }
		public int IdentityIndex { get; private set; }
		public string[] Columns { get; private set; }
		public string[] ColumnTypes { get; private set; }
		public bool[] InPrimaryKey { get; private set; }
		public string[] Properties { get; private set; }
		public string[] PropertyTypes { get; private set; }
		public string[] PropertyAttributes { get; private set; }
 
		internal CrudHost(Table table, string _namespace, string name, CrudOptionsEnum commandType) {
			Namespace = _namespace;
			Name = name;
 
			Schema = table.Schema;
			Table = table.Name;
 
			IdentityIndex = -1;
 
			int colCount = table.Columns.Count;
			Columns = new string[colCount];
			ColumnTypes = new string[colCount];
			InPrimaryKey = new bool[colCount];
			Properties = new string[colCount];
			PropertyTypes = new string[colCount];
			PropertyAttributes = new string[colCount];
 
			for (int i = 0; i < colCount; i++) {
				Column col = table.Columns[i];
				if(col.Identity)
					IdentityIndex = i;
				Columns[i] = col.Name;
				ColumnTypes[i] = col.DataType.Name;
				InPrimaryKey[i] = col.InPrimaryKey;
 
				ParameterDirection direction = ParameterDirection.Input;
				switch (commandType) {
					case CrudOptionsEnum.Insert:
						direction = col.Identity ? ParameterDirection.Output : ParameterDirection.Input;
						break;
 
					case CrudOptionsEnum.Select:
						direction = col.InPrimaryKey ? ParameterDirection.InputOutput : ParameterDirection.Output;
						break;
 
					case CrudOptionsEnum.SelectAll:
						direction = ParameterDirection.Output;
						break;
 
					case CrudOptionsEnum.Update:
						direction = ParameterDirection.Input;
						break;
 
					case CrudOptionsEnum.Delete:
						direction = ParameterDirection.Input;
						break;
				}
				var ph = PropertyHelper.CreatePropertyHelper(table.Parent, col.Name, col.DataType, col.Nullable, direction);
				Properties[i] = ph.Name;
				PropertyTypes[i] = ph.TypeName;
				PropertyAttributes[i] = ph.Attribute;
			}
		}
	}
}

Just a couple of final notes:

1) T4 templates are optional. If you remove some .tt files from the T4 folder (or remove the folder entirely), the AddIn will use the internal CRUD generator (released in the previous version) to generate CRUD commands/model with no .tt files.

2) The AddIn CommandBar buttons are now showing at the end of the Popup Menus (in case you missed them ;-) )

commandbars

Enjoy.

Leave a comment