忙话codesmith
为什么不是闲话,因为我很忙,项目中新问题是接连不断,上一篇讲到sqlite的并发问题,于是我又找了其它的嵌入式数据库Sqlserver CE compact 3.1/3.5也好不到哪去,万般无奈之下操起了berkeley db,为什么说是万般无奈呢?因为BDB(aka Berkeley DB)是非RDMBS,说白了你不能用sql.
BDB是一个大的哈希表,因为需要将原先储存在数据库中列以实体类转到字节的形式储存,OK,这里遇到一个问题,要生成实体类,实体类工具是一大把,mygeneration,codesmith,动软,之前都用过,可是原先的数据库是sqlite,一般的生成器可使不了这家伙,动软可以先排除了,本来想网上搜索一个轻便点的,结果找不到,于是down了一个新版的codesmith,找出以前我写的一套仿动软七层结构的模板(发现朗志项目的产出还挺大的,呵呵),拿出来改改,只是要生成个实体类,模板代码如下:
<% @ CodeTemplate Language = " C# " TargetLanguage = " C# " Description = " Generates a very simple business object. " %>
<% @ Property Name = " DevelopersName " Type = " String " Category = " Context " Default = " Lexus " Description = " The name to include in the comment header " %>
<% @ Property Name = " NameSpace " Type = " String " Category = " Context " Default = " Lexus " Description = " The namespace to use for this class " %>
<% @ Property Name = " SourceTable " Type = " SchemaExplorer.TableSchema " Category = " Context " Description = " Table that the object is based on. " %>
<% @ Assembly Name = " SchemaExplorer " %>
<% @ Assembly Name = " System.Data " %>
<% @ Import Namespace = " SchemaExplorer " %>
<% @ Import Namespace = " System.Data " %>
// File: <%= GetClassName(SourceTable) %>.cs
// <%=DateTime.Now.ToShortDateString() %>: <%=DevelopersName %> Original Version
//
// ===================================================================
[Serializable]
public class <%= GetClassName(SourceTable) %>
{
<% for ( int i = 0 ; i < SourceTable.Columns.Count; i ++ ) { %>
public <%= GetCSharpVariableType(SourceTable.Columns[i]) %> <%= SourceTable.Columns[i].Name %> { get ; set ;}
<% if (i < SourceTable.Columns.Count - 1 ) Response.Write( " \r\n " ); %>
<% } %>
}
< script runat = " template " >
script #region script
public string GetMemberVariableDeclarationStatement(ColumnSchema column)
{
return GetMemberVariableDeclarationStatement( " private " , column);
}
public string GetMemberVariableDeclarationStatement( string protectionLevel, ColumnSchema column)
{
string statement = protectionLevel + " " ;
statement += GetCSharpVariableType(column) + " " + GetMemberVariableName(column);
string defaultValue = GetMemberVariableDefaultValue(column);
if (defaultValue != "" )
{
statement += " = " + defaultValue;
}
statement += " ; " ;
return statement;
}
public string GetConstructorParameters()
{
string ret = "" ;
foreach (ColumnSchema column in SourceTable.Columns)
{
ret += GetCSharpVariableType(column) + " " + GetCamelCaseName(GetPropertyName(column)) + " ,\n\t\t\t " ;
}
return ret.Substring( 0 , ret.Length - 5 );
}
public string GetAssignValue()
{
string ret = "" ;
foreach (ColumnSchema column in SourceTable.Columns)
{
ret += GetMemberVariableName(column) + ( new String( ' ' , GetPropertyNameMaxLength() - GetPropertyNameLength(column))) + " = " + GetCamelCaseName(GetPropertyName(column)) + " ;\n\t\t\t " ;
}
return ret;
}
public string GetReaderAssignmentStatement(ColumnSchema column, int index)
{
string statement = " if (!reader.IsDBNull( " + index.ToString() + " )) " ;
statement += GetMemberVariableName(column) + " = " ;
if (column.Name.EndsWith( " TypeCode " )) statement += " ( " + column.Name + " ) " ;
statement += " reader. " + GetReaderMethod(column) + " ( " + index.ToString() + " ); " ;
return statement;
}
public string GetCamelCaseName( string value)
{
// return value.Substring(0, 1).ToLower() + value.Substring(1);
// lexus modify
return value;
}
public string GetMemberVariableName(ColumnSchema column)
{
// string propertyName = GetPropertyName(column);
string propertyName = column.Name;
string memberVariableName = " _ " + GetCamelCaseName(propertyName);
return memberVariableName;
}
public string GetPropertyName(ColumnSchema column)
{
string propertyName = column.Name;
if (propertyName == column.Table.Name + " Name " ) return " Name " ;
if (propertyName == column.Table.Name + " Description " ) return " Description " ;
if (propertyName.EndsWith( " TypeCode " )) propertyName = propertyName.Substring( 0 , propertyName.Length - 4 );
return propertyName;
}
public int GetPropertyNameLength(ColumnSchema column)
{
return (GetPropertyName(column)).Length;
}
public int GetPropertyNameMaxLength()
{
int ret = 0 ;
foreach (ColumnSchema column in SourceTable.Columns)
{
ret = ret < GetPropertyNameLength(column) ? GetPropertyNameLength(column):ret;
}
return ret;
}
public string GetMemberVariableDefaultValue(ColumnSchema column)
{
if (column.IsPrimaryKeyMember)
{
return "" ;
}
switch (column.DataType)
{
case DbType.Guid:
{
return " Guid.Empty " ;
}
case DbType.AnsiString:
case DbType.AnsiStringFixedLength:
case DbType.String:
case DbType.StringFixedLength:
{
return " String.Empty " ;
}
default :
{
return "" ;
}
}
}
public string GetCSharpVariableType(ColumnSchema column)
{
if (column.Name.EndsWith( " TypeCode " )) return column.Name;
switch (column.DataType)
{
case DbType.AnsiString: return " string " ;
case DbType.AnsiStringFixedLength: return " string " ;
case DbType.Binary: return " byte[] " ;
case DbType.Boolean: return " bool " ;
case DbType.Byte: return " byte " ;
case DbType.Currency: return " decimal " ;
case DbType.Date: return " DateTime " ;
case DbType.DateTime: return " DateTime " ;
case DbType.Decimal: return " decimal " ;
case DbType.Double: return " double " ;
case DbType.Guid: return " Guid " ;
case DbType.Int16: return " short " ;
case DbType.Int32: return " int " ;
case DbType.Int64: return " long " ;
case DbType.Object: return " object " ;
case DbType.SByte: return " sbyte " ;
case DbType.Single: return " float " ;
case DbType.String: return " string " ;
case DbType.StringFixedLength: return " string " ;
case DbType.Time: return " TimeSpan " ;
case DbType.UInt16: return " ushort " ;
case DbType.UInt32: return " uint " ;
case DbType.UInt64: return " ulong " ;
case DbType.VarNumeric: return " decimal " ;
default :
{
return " __UNKNOWN__ " + column.NativeType;
}
}
}
public string GetReaderMethod(ColumnSchema column)
{
switch (column.DataType)
{
case DbType.Byte:
{
return " GetByte " ;
}
case DbType.Int16:
{
return " GetInt16 " ;
}
case DbType.Int32:
{
return " GetInt32 " ;
}
case DbType.Int64:
{
return " GetInt64 " ;
}
case DbType.AnsiStringFixedLength:
case DbType.AnsiString:
case DbType.String:
case DbType.StringFixedLength:
{
return " GetString " ;
}
case DbType.Boolean:
{
return " GetBoolean " ;
}
case DbType.Guid:
{
return " GetGuid " ;
}
case DbType.Currency:
case DbType.Decimal:
{
return " GetDecimal " ;
}
case DbType.DateTime:
case DbType.Date:
{
return " GetDateTime " ;
}
case DbType.Binary:
{
return " GetBytes " ;
}
default :
{
return " __SQL__ " + column.DataType;
}
}
}
public string GetClassName(TableSchema table)
{
/**//*
if (table.Name.EndsWith("s"))
{
return table.Name.Substring(0, table.Name.Length - 1);
}
else
{
return table.Name;
}
*/
if (table == null )
{
return null ;
}
// lexus modify
// return table.Name + "Info";
int len = table.Name.Length;
string result = string .Empty;
if (table.Name.EndsWith( " ies " ))
{
result = table.Name.Substring( 0 ,len - 3 ) + " y " ;
}
else
{
result = table.Name.Substring( 0 ,len - 1 );
}
return result;
}
public string GetSqlDbType(ColumnSchema column)
{
switch (column.NativeType)
{
case " bigint " : return " BigInt " ;
case " binary " : return " Binary " ;
case " bit " : return " Bit " ;
case " char " : return " Char " ;
case " datetime " : return " DateTime " ;
case " decimal " : return " Decimal " ;
case " float " : return " Float " ;
case " image " : return " Image " ;
case " int " : return " Int " ;
case " money " : return " Money " ;
case " nchar " : return " NChar " ;
case " ntext " : return " NText " ;
case " numeric " : return " Decimal " ;
case " nvarchar " : return " NVarChar " ;
case " real " : return " Real " ;
case " smalldatetime " : return " SmallDateTime " ;
case " smallint " : return " SmallInt " ;
case " smallmoney " : return " SmallMoney " ;
case " sql_variant " : return " Variant " ;
case " sysname " : return " NChar " ;
case " text " : return " Text " ;
case " timestamp " : return " Timestamp " ;
case " tinyint " : return " TinyInt " ;
case " uniqueidentifier " : return " UniqueIdentifier " ;
case " varbinary " : return " VarBinary " ;
case " varchar " : return " VarChar " ;
default : return " __UNKNOWN__ " + column.NativeType;
}
}
public string GetPrimaryKeyType(TableSchema table)
{
if (table.PrimaryKey != null )
{
if (table.PrimaryKey.MemberColumns.Count == 1 )
{
return GetCSharpVariableType(table.PrimaryKey.MemberColumns[ 0 ]);
}
else
{
throw new ApplicationException( " This template will not work on primary keys with more than one member column. " );
}
}
else
{
throw new ApplicationException( " This template will only work on tables with a primary key. " );
}
}
public override string GetFileName()
{
return this .GetClassName( this .SourceTable) + " .cs " ;
}
#endregion script
</ script >
这个模板里有一些函数还是挺有用的,大家可以看看
另外,codesmith 4.1.2我用的版本,也不是一开始就支持sqlite的,这里引用了园友乱世经典修改后的驱动 http://www.cnblogs.com/chsword/archive/2008/07/08/sqliteschemaproviders.html
生成的数据类型还是有一些对不上,自己手工改一下吧,因为工作量不是很大,
最后也把仿动软的架构的模板提供给大家 https://files.cnblogs.com/lexus/new.zip ,由于我用的主键是guid,原来动软生成的代码有问题,我的模板改进了这个功能,大家如果在此基础上改进了,请mail给我