This is for Subsonic 3 (Final) and will not work for early versions.
For all those who may be having table naming issues with Subsonic3 T4 templates I have a quick and dirty (not really well thought out) snippet for renaming classes properly in case of conflict with C# Keywords or badly named table names (i.e. - tables starting with numbers).
First in the settings.ttinclude template I changed the CleanUp() method to the following (simple one liner):
string CleanUp(string tableName){
string result=tableName;
//strip blanks
result=result.Replace(" ","");
//put your logic here...
//return result;
return Inflector.CleanName(result);
}
Second, scroll down in the settings.ttinclude file to the Inflector class (not sure if this is the right place, but work with me) and add the following two static methods to the class.
public static string PrefixName(string name)
{
return "_" + name;
}
public static string CleanName(string name)
{
name= name.Replace("$","")
.Replace(" ", "_")
.Replace("-","_")
.Replace(".", "_")
.Replace(@"/","")
.Replace(@"\","")
.Replace("'","")
.Replace("#", "_");
if(name.Length>0)
{
int result;
if(int.TryParse(name.Substring(0, 1), out result))
{
name="_"+name;
}
}else{
name = "_NoName"; // add a date hashcode here
}
switch (name)
{
case "abstract":
return PrefixName(name);
break;
case "event":
return PrefixName(name);
break;
case "new":
return PrefixName(name);
break;
case "struct":
return PrefixName(name);
break;
case "as":
return PrefixName(name);
break;
case "explicit":
return PrefixName(name);
break;
case "null":
return PrefixName(name);
break;
case "switch":
return PrefixName(name);
break;
case "base":
return PrefixName(name);
break;
case "extern":
return PrefixName(name);
break;
case "object":
return PrefixName(name);
break;
case "this":
return PrefixName(name);
break;
case "bool":
return PrefixName(name);
break;
case "false":
return PrefixName(name);
break;
case "operator":
return PrefixName(name);
break;
case "throw":
return PrefixName(name);
break;
case "break":
return PrefixName(name);
break;
case "finally":
return PrefixName(name);
break;
case "out":
return PrefixName(name);
break;
case "true":
return PrefixName(name);
break;
case "byte":
return PrefixName(name);
break;
case "fixed":
return PrefixName(name);
break;
case "override":
return PrefixName(name);
break;
case "try":
return PrefixName(name);
break;
case "case":
return PrefixName(name);
break;
case "float":
return PrefixName(name);
break;
case "params":
return PrefixName(name);
break;
case "typeof":
return PrefixName(name);
break;
case "catch":
return PrefixName(name);
break;
case "for":
return PrefixName(name);
break;
case "private":
return PrefixName(name);
break;
case "uint":
return PrefixName(name);
break;
case "char":
return PrefixName(name);
break;
case "foreach":
return PrefixName(name);
break;
case "protected":
return PrefixName(name);
break;
case "ulong":
return PrefixName(name);
break;
case "checked":
return PrefixName(name);
break;
case "goto":
return PrefixName(name);
break;
case "public":
return PrefixName(name);
break;
case "unchecked":
return PrefixName(name);
break;
case "class":
return PrefixName(name);
break;
case "if":
return PrefixName(name);
break;
case "readonly":
return PrefixName(name);
break;
case "unsafe":
return PrefixName(name);
break;
case "const":
return PrefixName(name);
break;
case "implicit":
return PrefixName(name);
break;
case "ref":
return PrefixName(name);
break;
case "case ":
return PrefixName(name);
break;
case "ushort":
return PrefixName(name);
break;
case "continue":
return PrefixName(name);
break;
case "in":
return PrefixName(name);
break;
case "return":
return PrefixName(name);
break;
case "using":
return PrefixName(name);
break;
case "decimal":
return PrefixName(name);
break;
case "int":
return PrefixName(name);
break;
case "sbyte":
return PrefixName(name);
break;
case "virtual":
return PrefixName(name);
break;
case "default":
return PrefixName(name);
break;
case "interface":
return PrefixName(name);
break;
case "sealed":
return PrefixName(name);
break;
case "volatile":
return PrefixName(name);
break;
case "delegate":
return PrefixName(name);
break;
case "internal":
return PrefixName(name);
break;
case "short":
return PrefixName(name);
break;
case "void":
return PrefixName(name);
break;
case "do":
return PrefixName(name);
break;
case "is":
return PrefixName(name);
break;
case "sizeof":
return PrefixName(name);
break;
case "while":
return PrefixName(name);
break;
case "double":
return PrefixName(name);
break;
case "lock":
return PrefixName(name);
break;
case "stackalloc":
return PrefixName(name);
break;
case "else":
return PrefixName(name);
break;
case "long":
return PrefixName(name);
break;
case "static":
return PrefixName(name);
break;
case "enum":
return PrefixName(name);
break;
case "namespace":
return PrefixName(name);
break;
case "string":
return PrefixName(name);
break;
case "from":
return PrefixName(name);
break;
case "get":
return PrefixName(name);
break;
case "group":
return PrefixName(name);
break;
case "into":
return PrefixName(name);
break;
case "join":
return PrefixName(name);
break;
case "let":
return PrefixName(name);
break;
case "orderby":
return PrefixName(name);
break;
case "partial":
return PrefixName(name);
break;
case "select":
return PrefixName(name);
break;
case "set":
return PrefixName(name);
break;
case "value":
return PrefixName(name);
break;
case "var":
return PrefixName(name);
break;
case "where":
return PrefixName(name);
break;
case "yield":
return PrefixName(name);
break;
default:
return name;
}
}
That's it! All done, it may not fix everything but it fixed everything for my particular database. Feel free to modify and contribute back to community. My database suffered from having table names like "__" (without parens) and 2006Statistics, etc... in some cases, some had the same names as the c# keywords and the big switch statement totally worked.