diff --git a/CodeSmith/CSharp/Entity.cst b/CodeSmith/CSharp/Entity.cst
index 819211ce..90952b98 100644
--- a/CodeSmith/CSharp/Entity.cst
+++ b/CodeSmith/CSharp/Entity.cst
@@ -1,309 +1,309 @@
-<%@ Template Language="C#" TargetLanguage="Text" Debug="True" OutputType="None" %>
-
-<%@ Assembly Name="SchemaExplorer" %>
-<%@ Assembly Name="CodeSmith.CustomProperties" %>
-
-<%@ Assembly Name="Mono.Cecil" Path="..\Common" %>
-<%@ Assembly Name="ICSharpCode.NRefactory" Path="..\Common" %>
-<%@ Assembly Name="ICSharpCode.NRefactory.CSharp" Path="..\Common" %>
-
-<%@ Assembly Src="Internal\Model.cs" %>
-<%@ Assembly Src="Internal\Extensions.cs" %>
-<%@ Assembly Src="Internal\Generator.cs" %>
-<%@ Assembly Src="Internal\Parser.cs" %>
-
-<%@ Import Namespace="System.Collections.Generic" %>
-<%@ Import Namespace="System.IO" %>
-<%@ Import Namespace="System.Linq" %>
-<%@ Import Namespace="System.Text" %>
-<%@ Import Namespace="System.Text.RegularExpressions" %>
-
-<%@ Import Namespace="SchemaMapper" %>
-
-<%@ Property Name="SourceDatabase"
- Type="SchemaExplorer.DatabaseSchema"
- Category="1.Database"
- OnChanged="OnSourceDatabaseChanged"
- Description="The source database." %>
-
-<%@ Property Name="ContextNamespace"
- Type="System.String"
- Category="2.Class"
- OnChanged="OnContextNamespaceChanged"
- Description="The namespace to use for the data context class files."%>
-<%@ Property Name="EntityNamespace"
- Type="System.String"
- Category="2.Class"
- Description="The namespace to use for the entity class files."%>
-<%@ Property Name="MappingNamespace"
- Type="System.String"
- Category="2.Class"
- Description="The namespace to use for the mapping class files."%>
-
-<%@ Property Name="ContextDirectory"
- Category="3.Output"
- Type="System.String"
- Default=".\"
- Optional="True"
- Description="The folder to save the generated context files."
- Editor="System.Windows.Forms.Design.FolderNameEditor, System.Design, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" %>
-<%@ Property Name="EntityDirectory"
- Category="3.Output"
- Type="System.String"
- Default=".\Entities"
- Optional="True"
- Description="The folder to save the generated entity files."
- Editor="System.Windows.Forms.Design.FolderNameEditor, System.Design, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" %>
-<%@ Property Name="MappingDirectory"
- Category="3.Output"
- Type="System.String"
- Default=".\Mapping"
- Optional="True"
- Description="The folder to save the generated mapping files."
- Editor="System.Windows.Forms.Design.FolderNameEditor, System.Design, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" %>
-
-<%@ Property Name="TableNaming"
- Type="SchemaMapper.TableNaming"
- Category="4.Hints"
- Default="Singular"
- Description="Provide generator a hint as to how the tables are named." %>
-<%@ Property Name="EntityNaming"
- Type="SchemaMapper.EntityNaming"
- Category="4.Hints"
- Default="Singular"
- Description="Tell generator how the entities are to be named." %>
-<%@ Property Name="RelationshipNaming"
- Type="SchemaMapper.RelationshipNaming"
- Category="4.Hints"
- Default="Plural"
- Description="Tell generator how the relationships are to be named." %>
-<%@ Property Name="ContextNaming"
- Type="SchemaMapper.ContextNaming"
- Category="4.Hints"
- Default="Plural"
- Description="Tell generator how the context properties are to be named." %>
-
-<%@ Property Name="IgnoreList"
- Type="CodeSmith.CustomProperties.StringCollection"
- Category="5.Customization"
- Default="sysdiagrams$"
- Optional="True"
- Description="List of regular expressions to ignore tables, views and commands when generating mapping." %>
-<%@ Property Name="InclusionMode"
- Type="Boolean"
- Category="5.Customization"
- Default="False"
- Optional="True"
- Description="Change the IgnoreList to be a list of table to include instead of ignore." %>
-<%@ Property Name="CleanExpressions"
- Type="CodeSmith.CustomProperties.StringCollection"
- Category="5.Customization"
- Default="^(sp|tbl|udf|vw)_"
- Optional="True"
- Description="List of regular expressions to clean table, view and column names." %>
-<%@ Property Name="InterfaceMode"
- Type="Boolean"
- Category="5.Customization"
- Default="False"
- Optional="True"
- Description="Use interfaces for DbContext." %>
-
-
-
-<%@ Register Name="ContextGeneratedClass"
- Template="Internal\Context.Generated.cst"
- MergeProperties="False" %>
-
-<%@ Register Name="EntityGeneratedClass"
- Template="Internal\Entity.Generated.cst"
- MergeProperties="False" %>
-
-<%@ Register Name="MappingGeneratedClass"
- Template="Internal\Mapping.Generated.cst"
- MergeProperties="False" %>
-
-Generating Entities ...
-<% Generate(); %>
-
-
\ No newline at end of file
diff --git a/CodeSmith/CSharp/Internal/Context.Generated.cst b/CodeSmith/CSharp/Internal/Context.Generated.cst
index df3d3a21..a3539d79 100644
--- a/CodeSmith/CSharp/Internal/Context.Generated.cst
+++ b/CodeSmith/CSharp/Internal/Context.Generated.cst
@@ -1,89 +1,89 @@
-<%@ Template Language="C#" TargetLanguage="C#" Debug="True" Encoding="UTF-8" %>
-
-<%@ Assembly Src="Model.cs" %>
-<%@ Assembly Src="Extensions.cs" %>
-
-<%@ Import Namespace="System.Collections.Generic" %>
-<%@ Import Namespace="System.Linq" %>
-<%@ Import Namespace="System.Text" %>
-<%@ Import Namespace="System.Text.RegularExpressions" %>
-
-<%@ Import Namespace="SchemaMapper" %>
-
-<%@ Property Name="EntityContext" Type="SchemaMapper.EntityContext" %>
-
-<%@ Property Name="ContextNamespace" Type="System.String" %>
-<%@ Property Name="EntityNamespace" Type="System.String" %>
-<%@ Property Name="MappingNamespace" Type="System.String" %>
-<%@ Property Name="InterfaceMode" Type="Boolean" Default="False" Optional="True" %>
-
-//------------------------------------------------------------------------------
-//
-// This code was generated by a CodeSmith Template.
-//
-// DO NOT MODIFY contents of this file. Changes to this
-// file will be lost if the code is regenerated.
-//
-//------------------------------------------------------------------------------
-using System;
-using System.Data.Entity;
-using System.Collections.Generic;
-using <%= EntityNamespace %>;
-using <%= MappingNamespace %>;
-
-namespace <%= ContextNamespace %>
-{
-<% if (InterfaceMode) { %>
- public interface IDbContext : IDisposable
- {
- System.Data.Entity.Database Database { get; }
- System.Data.Entity.Infrastructure.DbChangeTracker ChangeTracker { get; }
- System.Data.Entity.Infrastructure.DbContextConfiguration Configuration { get; }
-
- System.Data.Entity.Infrastructure.DbEntityEntry Entry(object entity);
- System.Data.Entity.Infrastructure.DbEntityEntry Entry(TEntity entity) where TEntity : class;
-
- IEnumerable GetValidationErrors();
-
- System.Data.Entity.DbSet Set(Type entityType);
- System.Data.Entity.IDbSet Set() where TEntity : class;
-
- int SaveChanges();
- }
-
- public partial interface I<%= EntityContext.ClassName.ToSafeName() %> : IDbContext
- {
-<% foreach(var p in EntityContext.Entities) { %>
- System.Data.Entity.IDbSet<<%= EntityNamespace %>.<%= p.ClassName.ToSafeName() %>> <%= p.ContextName.ToSafeName() %> { get; set; }
-<% } // foreach %>
- }
-
-<% } // if interface %>
- public partial class <%= EntityContext.ClassName.ToSafeName() %>: DbContext<%= InterfaceMode ? ", I" + EntityContext.ClassName.ToSafeName() : string.Empty %>
- {
- static <%= EntityContext.ClassName.ToSafeName() %>()
- {
- Database.SetInitializer< <%= EntityContext.ClassName.ToSafeName() %>>(null);
- }
- public <%= EntityContext.ClassName.ToSafeName() %>()
- :base("Name=<%= EntityContext.ClassName.ToSafeName() %>")
- { }
-
- public <%= EntityContext.ClassName.ToSafeName() %>(string nameOrConnectionString)
- : base(nameOrConnectionString)
- { }
-
-<% foreach(var p in EntityContext.Entities) { %>
- public System.Data.Entity.<%= InterfaceMode ? "I" : "" %>DbSet<<%= p.ClassName.ToSafeName() %>> <%= p.ContextName.ToSafeName() %> { get; set; }
-<% } // foreach %>
-
-
-<% if (InterfaceMode) { %>
-
- System.Data.Entity.IDbSet IDbContext.Set()
- {
- return base.Set();
- }
-<% } // if interface %>
- }
+<%@ Template Language="C#" TargetLanguage="C#" Debug="True" Encoding="UTF-8" %>
+
+<%@ Assembly Src="Model.cs" %>
+<%@ Assembly Src="Extensions.cs" %>
+
+<%@ Import Namespace="System.Collections.Generic" %>
+<%@ Import Namespace="System.Linq" %>
+<%@ Import Namespace="System.Text" %>
+<%@ Import Namespace="System.Text.RegularExpressions" %>
+
+<%@ Import Namespace="SchemaMapper" %>
+
+<%@ Property Name="EntityContext" Type="SchemaMapper.EntityContext" %>
+
+<%@ Property Name="ContextNamespace" Type="System.String" %>
+<%@ Property Name="EntityNamespace" Type="System.String" %>
+<%@ Property Name="MappingNamespace" Type="System.String" %>
+<%@ Property Name="InterfaceMode" Type="Boolean" Default="False" Optional="True" %>
+
+//------------------------------------------------------------------------------
+//
+// This code was generated by a CodeSmith Template.
+//
+// DO NOT MODIFY contents of this file. Changes to this
+// file will be lost if the code is regenerated.
+//
+//------------------------------------------------------------------------------
+using System;
+using System.Data.Entity;
+using System.Collections.Generic;
+using <%= EntityNamespace %>;
+using <%= MappingNamespace %>;
+
+namespace <%= ContextNamespace %>
+{
+<% if (InterfaceMode) { %>
+ public interface IDbContext : IDisposable
+ {
+ System.Data.Entity.Database Database { get; }
+ System.Data.Entity.Infrastructure.DbChangeTracker ChangeTracker { get; }
+ System.Data.Entity.Infrastructure.DbContextConfiguration Configuration { get; }
+
+ System.Data.Entity.Infrastructure.DbEntityEntry Entry(object entity);
+ System.Data.Entity.Infrastructure.DbEntityEntry Entry(TEntity entity) where TEntity : class;
+
+ IEnumerable GetValidationErrors();
+
+ System.Data.Entity.DbSet Set(Type entityType);
+ System.Data.Entity.IDbSet Set() where TEntity : class;
+
+ int SaveChanges();
+ }
+
+ public partial interface I<%= EntityContext.ClassName.ToSafeName() %> : IDbContext
+ {
+<% foreach(var p in EntityContext.Entities) { %>
+ System.Data.Entity.IDbSet<<%= EntityNamespace %>.<%= p.ClassName.ToSafeName() %>> <%= p.ContextName.ToSafeName() %> { get; set; }
+<% } // foreach %>
+ }
+
+<% } // if interface %>
+ public partial class <%= EntityContext.ClassName.ToSafeName() %>: DbContext<%= InterfaceMode ? ", I" + EntityContext.ClassName.ToSafeName() : string.Empty %>
+ {
+ static <%= EntityContext.ClassName.ToSafeName() %>()
+ {
+ Database.SetInitializer< <%= EntityContext.ClassName.ToSafeName() %>>(null);
+ }
+ public <%= EntityContext.ClassName.ToSafeName() %>()
+ :base("Name=<%= EntityContext.ClassName.ToSafeName() %>")
+ { }
+
+ public <%= EntityContext.ClassName.ToSafeName() %>(string nameOrConnectionString)
+ : base(nameOrConnectionString)
+ { }
+
+<% foreach(var p in EntityContext.Entities) { %>
+ public System.Data.Entity.<%= InterfaceMode ? "I" : "" %>DbSet<<%= p.ClassName.ToSafeName() %>> <%= p.ContextName.ToSafeName() %> { get; set; }
+<% } // foreach %>
+
+
+<% if (InterfaceMode) { %>
+
+ System.Data.Entity.IDbSet IDbContext.Set()
+ {
+ return base.Set();
+ }
+<% } // if interface %>
+ }
}
\ No newline at end of file
diff --git a/CodeSmith/CSharp/Internal/Entity.Generated.cst b/CodeSmith/CSharp/Internal/Entity.Generated.cst
index d387ffed..632d50d9 100644
--- a/CodeSmith/CSharp/Internal/Entity.Generated.cst
+++ b/CodeSmith/CSharp/Internal/Entity.Generated.cst
@@ -1,72 +1,72 @@
-<%@ Template Language="C#" TargetLanguage="C#" Debug="True" Encoding="UTF-8" %>
-
-<%@ Assembly Src="Model.cs" %>
-<%@ Assembly Src="Extensions.cs" %>
-
-<%@ Import Namespace="System.Collections.Generic" %>
-<%@ Import Namespace="System.Linq" %>
-<%@ Import Namespace="System.Text" %>
-<%@ Import Namespace="System.Text.RegularExpressions" %>
-
-<%@ Import Namespace="SchemaMapper" %>
-
-<%@ Property Name="Entity"
- Type="SchemaMapper.Entity" %>
-
-<%@ Property Name="EntityNamespace"
- Type="System.String" %>
-//------------------------------------------------------------------------------
-//
-// This code was generated by a CodeSmith Template.
-//
-// DO NOT MODIFY contents of this file. Changes to this
-// file will be lost if the code is regenerated.
-// Author:Yubao Li
-//
-//------------------------------------------------------------------------------
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace <%= EntityNamespace %>
-{
- ///
- /// <%= Entity.Description %>
- ///
- public partial class <%= Entity.ClassName.ToSafeName() %> : Entity
- {
- public <%= Entity.ClassName.ToSafeName() %>()
- {
-<% foreach(var p in Entity.Properties) {
- if(p.IsPrimaryKey ==true) continue;
- string type = p.SystemType.ToNullableType(p.IsNullable == true);
- if(type =="int" || type=="decimal")
- Response.WriteLine(" this."+p.PropertyName.ToSafeName()+"= 0;");
- else if(type =="string")
- Response.WriteLine(" this."+p.PropertyName.ToSafeName()+"= string.Empty;");
- else if(type.ToLower().Contains("datetime"))
- Response.WriteLine(" this."+p.PropertyName.ToSafeName()+"= DateTime.Now;");
- } // foreach %>
-<% foreach(var r in Entity.Relationships.Where(e => e.ThisCardinality == Cardinality.Many)) { %>
- <%= r.ThisPropertyName.ToSafeName() %> = new List<<%= r.OtherEntity.ToSafeName() %>>();
-<% } // foreach %>
- }
-
-<% foreach(var p in Entity.Properties) {
- if(p.IsPrimaryKey ==true) continue;
- %>
- ///
- /// <%=p.Description %>
- ///
- public <%= p.SystemType.ToNullableType(p.IsNullable == true) %> <%= p.PropertyName.ToSafeName() %> { get; set; }
-<% } // foreach %>
-
-<% foreach(var r in Entity.Relationships) { %>
-<% if(r.ThisCardinality == Cardinality.Many) { %>
- public virtual ICollection<<%= r.OtherEntity.ToSafeName() %>> <%= r.ThisPropertyName.ToSafeName() %> { get; set; }
-<% } else { %>
- public virtual <%= r.OtherEntity.ToSafeName() %> <%= r.ThisPropertyName.ToSafeName() %> { get; set; }
-<% } %>
-<% } // foreach %>
- }
+<%@ Template Language="C#" TargetLanguage="C#" Debug="True" Encoding="UTF-8" %>
+
+<%@ Assembly Src="Model.cs" %>
+<%@ Assembly Src="Extensions.cs" %>
+
+<%@ Import Namespace="System.Collections.Generic" %>
+<%@ Import Namespace="System.Linq" %>
+<%@ Import Namespace="System.Text" %>
+<%@ Import Namespace="System.Text.RegularExpressions" %>
+
+<%@ Import Namespace="SchemaMapper" %>
+
+<%@ Property Name="Entity"
+ Type="SchemaMapper.Entity" %>
+
+<%@ Property Name="EntityNamespace"
+ Type="System.String" %>
+//------------------------------------------------------------------------------
+//
+// This code was generated by a CodeSmith Template.
+//
+// DO NOT MODIFY contents of this file. Changes to this
+// file will be lost if the code is regenerated.
+// Author:Yubao Li
+//
+//------------------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace <%= EntityNamespace %>
+{
+ ///
+ /// <%= Entity.Description %>
+ ///
+ public partial class <%= Entity.ClassName.ToSafeName() %> : Entity
+ {
+ public <%= Entity.ClassName.ToSafeName() %>()
+ {
+<% foreach(var p in Entity.Properties) {
+ if(p.IsPrimaryKey ==true) continue;
+ string type = p.SystemType.ToNullableType(p.IsNullable == true);
+ if(type =="int" || type=="decimal")
+ Response.WriteLine(" this."+p.PropertyName.ToSafeName()+"= 0;");
+ else if(type =="string")
+ Response.WriteLine(" this."+p.PropertyName.ToSafeName()+"= string.Empty;");
+ else if(type.ToLower().Contains("datetime"))
+ Response.WriteLine(" this."+p.PropertyName.ToSafeName()+"= DateTime.Now;");
+ } // foreach %>
+<% foreach(var r in Entity.Relationships.Where(e => e.ThisCardinality == Cardinality.Many)) { %>
+ <%= r.ThisPropertyName.ToSafeName() %> = new List<<%= r.OtherEntity.ToSafeName() %>>();
+<% } // foreach %>
+ }
+
+<% foreach(var p in Entity.Properties) {
+ if(p.IsPrimaryKey ==true) continue;
+ %>
+ ///
+ /// <%=p.Description %>
+ ///
+ public <%= p.SystemType.ToNullableType(p.IsNullable == true) %> <%= p.PropertyName.ToSafeName() %> { get; set; }
+<% } // foreach %>
+
+<% foreach(var r in Entity.Relationships) { %>
+<% if(r.ThisCardinality == Cardinality.Many) { %>
+ public virtual ICollection<<%= r.OtherEntity.ToSafeName() %>> <%= r.ThisPropertyName.ToSafeName() %> { get; set; }
+<% } else { %>
+ public virtual <%= r.OtherEntity.ToSafeName() %> <%= r.ThisPropertyName.ToSafeName() %> { get; set; }
+<% } %>
+<% } // foreach %>
+ }
}
\ No newline at end of file
diff --git a/CodeSmith/CSharp/Internal/Extensions.cs b/CodeSmith/CSharp/Internal/Extensions.cs
index 0e8dc289..41fffbf1 100644
--- a/CodeSmith/CSharp/Internal/Extensions.cs
+++ b/CodeSmith/CSharp/Internal/Extensions.cs
@@ -1,187 +1,187 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using CodeSmith.Engine;
-
-namespace SchemaMapper
-{
- public enum CodeLanguage
- {
- CSharp,
- VisualBasic
- }
-
- public static class Extensions
- {
- private static readonly HashSet _csharpKeywords;
- private static readonly HashSet _visualBasicKeywords;
- private static readonly Dictionary _csharpTypeAlias;
-
- static Extensions()
- {
- _csharpKeywords = new HashSet(StringComparer.Ordinal)
- {
- "as", "do", "if", "in", "is",
- "for", "int", "new", "out", "ref", "try",
- "base", "bool", "byte", "case", "char", "else", "enum", "goto", "lock", "long", "null", "this", "true", "uint", "void",
- "break", "catch", "class", "const", "event", "false", "fixed", "float", "sbyte", "short", "throw", "ulong", "using", "while",
- "double", "extern", "object", "params", "public", "return", "sealed", "sizeof", "static", "string", "struct", "switch", "typeof", "unsafe", "ushort",
- "checked", "decimal", "default", "finally", "foreach", "private", "virtual",
- "abstract", "continue", "delegate", "explicit", "implicit", "internal", "operator", "override", "readonly", "volatile",
- "__arglist", "__makeref", "__reftype", "interface", "namespace", "protected", "unchecked",
- "__refvalue", "stackalloc"
- };
-
- _visualBasicKeywords = new HashSet(StringComparer.OrdinalIgnoreCase)
- {
- "as", "do", "if", "in", "is", "me", "of", "on", "or", "to",
- "and", "dim", "end", "for", "get", "let", "lib", "mod", "new", "not", "rem", "set", "sub", "try", "xor",
- "ansi", "auto", "byte", "call", "case", "cdbl", "cdec", "char", "cint", "clng", "cobj", "csng", "cstr", "date", "each", "else",
- "enum", "exit", "goto", "like", "long", "loop", "next", "step", "stop", "then", "true", "wend", "when", "with",
- "alias", "byref", "byval", "catch", "cbool", "cbyte", "cchar", "cdate", "class", "const", "ctype", "cuint", "culng", "endif", "erase", "error",
- "event", "false", "gosub", "isnot", "redim", "sbyte", "short", "throw", "ulong", "until", "using", "while",
- "csbyte", "cshort", "double", "elseif", "friend", "global", "module", "mybase", "object", "option", "orelse", "public", "resume", "return", "select", "shared",
- "single", "static", "string", "typeof", "ushort",
- "andalso", "boolean", "cushort", "decimal", "declare", "default", "finally", "gettype", "handles", "imports", "integer", "myclass", "nothing", "partial", "private", "shadows",
- "trycast", "unicode", "variant",
- "assembly", "continue", "delegate", "function", "inherits", "operator", "optional", "preserve", "property", "readonly", "synclock", "uinteger", "widening",
- "addressof", "interface", "namespace", "narrowing", "overloads", "overrides", "protected", "structure", "writeonly",
- "addhandler", "directcast", "implements", "paramarray", "raiseevent", "withevents",
- "mustinherit", "overridable",
- "mustoverride",
- "removehandler",
- "class_finalize", "notinheritable", "notoverridable",
- "class_initialize"
- };
-
- _csharpTypeAlias = new Dictionary(16)
- {
- {"System.Int16", "short"},
- {"System.Int32", "int"},
- {"System.Int64", "long"},
- {"System.String", "string"},
- {"System.Object", "object"},
- {"System.Boolean", "bool"},
- {"System.Void", "void"},
- {"System.Char", "char"},
- {"System.Byte", "byte"},
- {"System.UInt16", "ushort"},
- {"System.UInt32", "uint"},
- {"System.UInt64", "ulong"},
- {"System.SByte", "sbyte"},
- {"System.Single", "float"},
- {"System.Double", "double"},
- {"System.Decimal", "decimal"}
- };
- }
-
- public static string ToCamelCase(this string name)
- {
- return StringUtil.ToCamelCase(name);
- }
-
- public static string ToPascalCase(this string name)
- {
- return StringUtil.ToPascalCase(name);
- }
-
-
- public static string ToFieldName(this string name)
- {
- return "_" + StringUtil.ToCamelCase(name);
- }
-
- public static string MakeUnique(this string name, Func exists)
- {
- string uniqueName = name;
- int count = 1;
-
- while (exists(uniqueName))
- uniqueName = string.Concat(name, count++);
-
- return uniqueName;
- }
-
- public static bool IsKeyword(this string text, CodeLanguage language = CodeLanguage.CSharp)
- {
- return language == CodeLanguage.VisualBasic
- ? _visualBasicKeywords.Contains(text)
- : _csharpKeywords.Contains(text);
- }
-
- public static string ToSafeName(this string name, CodeLanguage language = CodeLanguage.CSharp)
- {
- if (!name.IsKeyword(language))
- return name;
-
- return language == CodeLanguage.VisualBasic
- ? string.Format("[{0}]", name)
- : "@" + name;
- }
-
- public static string ToType(this Type type, CodeLanguage language = CodeLanguage.CSharp)
- {
- return ToType(type.FullName, language);
- }
-
- public static string ToType(this string type, CodeLanguage language = CodeLanguage.CSharp)
- {
- if (type == "System.Xml.XmlDocument")
- type = "System.String";
-
- string t;
- if (language == CodeLanguage.CSharp && _csharpTypeAlias.TryGetValue(type, out t))
- return t;
-
-
- return type;
- }
-
- public static string ToNullableType(this Type type, bool isNullable = false, CodeLanguage language = CodeLanguage.CSharp)
- {
- return ToNullableType(type.FullName, isNullable, language);
- }
-
- public static string ToNullableType(this string type, bool isNullable = false, CodeLanguage language = CodeLanguage.CSharp)
- {
- bool isValueType = type.IsValueType();
-
- type = type.ToType(language);
-
- if (!isValueType || !isNullable)
- return type;
-
- return language == CodeLanguage.VisualBasic
- ? string.Format("Nullable(Of {0})", type)
- : type + "?";
- }
-
- public static bool IsValueType(this string type)
- {
- if (!type.StartsWith("System."))
- return false;
-
- var t = Type.GetType(type, false);
- return t != null && t.IsValueType;
- }
-
- public static string ToDelimitedString(this IEnumerable values, string delimiter, string format = null)
- {
- var sb = new StringBuilder();
- foreach (var i in values)
- {
- if (sb.Length > 0)
- sb.Append(delimiter);
-
- if (string.IsNullOrEmpty(format))
- sb.Append(i);
- else
- sb.AppendFormat(format, i);
- }
-
- return sb.ToString();
- }
-
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using CodeSmith.Engine;
+
+namespace SchemaMapper
+{
+ public enum CodeLanguage
+ {
+ CSharp,
+ VisualBasic
+ }
+
+ public static class Extensions
+ {
+ private static readonly HashSet _csharpKeywords;
+ private static readonly HashSet _visualBasicKeywords;
+ private static readonly Dictionary _csharpTypeAlias;
+
+ static Extensions()
+ {
+ _csharpKeywords = new HashSet(StringComparer.Ordinal)
+ {
+ "as", "do", "if", "in", "is",
+ "for", "int", "new", "out", "ref", "try",
+ "base", "bool", "byte", "case", "char", "else", "enum", "goto", "lock", "long", "null", "this", "true", "uint", "void",
+ "break", "catch", "class", "const", "event", "false", "fixed", "float", "sbyte", "short", "throw", "ulong", "using", "while",
+ "double", "extern", "object", "params", "public", "return", "sealed", "sizeof", "static", "string", "struct", "switch", "typeof", "unsafe", "ushort",
+ "checked", "decimal", "default", "finally", "foreach", "private", "virtual",
+ "abstract", "continue", "delegate", "explicit", "implicit", "internal", "operator", "override", "readonly", "volatile",
+ "__arglist", "__makeref", "__reftype", "interface", "namespace", "protected", "unchecked",
+ "__refvalue", "stackalloc"
+ };
+
+ _visualBasicKeywords = new HashSet(StringComparer.OrdinalIgnoreCase)
+ {
+ "as", "do", "if", "in", "is", "me", "of", "on", "or", "to",
+ "and", "dim", "end", "for", "get", "let", "lib", "mod", "new", "not", "rem", "set", "sub", "try", "xor",
+ "ansi", "auto", "byte", "call", "case", "cdbl", "cdec", "char", "cint", "clng", "cobj", "csng", "cstr", "date", "each", "else",
+ "enum", "exit", "goto", "like", "long", "loop", "next", "step", "stop", "then", "true", "wend", "when", "with",
+ "alias", "byref", "byval", "catch", "cbool", "cbyte", "cchar", "cdate", "class", "const", "ctype", "cuint", "culng", "endif", "erase", "error",
+ "event", "false", "gosub", "isnot", "redim", "sbyte", "short", "throw", "ulong", "until", "using", "while",
+ "csbyte", "cshort", "double", "elseif", "friend", "global", "module", "mybase", "object", "option", "orelse", "public", "resume", "return", "select", "shared",
+ "single", "static", "string", "typeof", "ushort",
+ "andalso", "boolean", "cushort", "decimal", "declare", "default", "finally", "gettype", "handles", "imports", "integer", "myclass", "nothing", "partial", "private", "shadows",
+ "trycast", "unicode", "variant",
+ "assembly", "continue", "delegate", "function", "inherits", "operator", "optional", "preserve", "property", "readonly", "synclock", "uinteger", "widening",
+ "addressof", "interface", "namespace", "narrowing", "overloads", "overrides", "protected", "structure", "writeonly",
+ "addhandler", "directcast", "implements", "paramarray", "raiseevent", "withevents",
+ "mustinherit", "overridable",
+ "mustoverride",
+ "removehandler",
+ "class_finalize", "notinheritable", "notoverridable",
+ "class_initialize"
+ };
+
+ _csharpTypeAlias = new Dictionary(16)
+ {
+ {"System.Int16", "short"},
+ {"System.Int32", "int"},
+ {"System.Int64", "long"},
+ {"System.String", "string"},
+ {"System.Object", "object"},
+ {"System.Boolean", "bool"},
+ {"System.Void", "void"},
+ {"System.Char", "char"},
+ {"System.Byte", "byte"},
+ {"System.UInt16", "ushort"},
+ {"System.UInt32", "uint"},
+ {"System.UInt64", "ulong"},
+ {"System.SByte", "sbyte"},
+ {"System.Single", "float"},
+ {"System.Double", "double"},
+ {"System.Decimal", "decimal"}
+ };
+ }
+
+ public static string ToCamelCase(this string name)
+ {
+ return StringUtil.ToCamelCase(name);
+ }
+
+ public static string ToPascalCase(this string name)
+ {
+ return StringUtil.ToPascalCase(name);
+ }
+
+
+ public static string ToFieldName(this string name)
+ {
+ return "_" + StringUtil.ToCamelCase(name);
+ }
+
+ public static string MakeUnique(this string name, Func exists)
+ {
+ string uniqueName = name;
+ int count = 1;
+
+ while (exists(uniqueName))
+ uniqueName = string.Concat(name, count++);
+
+ return uniqueName;
+ }
+
+ public static bool IsKeyword(this string text, CodeLanguage language = CodeLanguage.CSharp)
+ {
+ return language == CodeLanguage.VisualBasic
+ ? _visualBasicKeywords.Contains(text)
+ : _csharpKeywords.Contains(text);
+ }
+
+ public static string ToSafeName(this string name, CodeLanguage language = CodeLanguage.CSharp)
+ {
+ if (!name.IsKeyword(language))
+ return name;
+
+ return language == CodeLanguage.VisualBasic
+ ? string.Format("[{0}]", name)
+ : "@" + name;
+ }
+
+ public static string ToType(this Type type, CodeLanguage language = CodeLanguage.CSharp)
+ {
+ return ToType(type.FullName, language);
+ }
+
+ public static string ToType(this string type, CodeLanguage language = CodeLanguage.CSharp)
+ {
+ if (type == "System.Xml.XmlDocument")
+ type = "System.String";
+
+ string t;
+ if (language == CodeLanguage.CSharp && _csharpTypeAlias.TryGetValue(type, out t))
+ return t;
+
+
+ return type;
+ }
+
+ public static string ToNullableType(this Type type, bool isNullable = false, CodeLanguage language = CodeLanguage.CSharp)
+ {
+ return ToNullableType(type.FullName, isNullable, language);
+ }
+
+ public static string ToNullableType(this string type, bool isNullable = false, CodeLanguage language = CodeLanguage.CSharp)
+ {
+ bool isValueType = type.IsValueType();
+
+ type = type.ToType(language);
+
+ if (!isValueType || !isNullable)
+ return type;
+
+ return language == CodeLanguage.VisualBasic
+ ? string.Format("Nullable(Of {0})", type)
+ : type + "?";
+ }
+
+ public static bool IsValueType(this string type)
+ {
+ if (!type.StartsWith("System."))
+ return false;
+
+ var t = Type.GetType(type, false);
+ return t != null && t.IsValueType;
+ }
+
+ public static string ToDelimitedString(this IEnumerable values, string delimiter, string format = null)
+ {
+ var sb = new StringBuilder();
+ foreach (var i in values)
+ {
+ if (sb.Length > 0)
+ sb.Append(delimiter);
+
+ if (string.IsNullOrEmpty(format))
+ sb.Append(i);
+ else
+ sb.AppendFormat(format, i);
+ }
+
+ return sb.ToString();
+ }
+
+ }
+}
diff --git a/CodeSmith/CSharp/Internal/Generator.cs b/CodeSmith/CSharp/Internal/Generator.cs
index b5ffa8e4..c3ecd1c6 100644
--- a/CodeSmith/CSharp/Internal/Generator.cs
+++ b/CodeSmith/CSharp/Internal/Generator.cs
@@ -1,816 +1,816 @@
-using System;
-using System.Collections;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Linq;
-using System.Text.RegularExpressions;
-using CodeSmith.Engine;
-using SchemaExplorer;
-
-namespace SchemaMapper
-{
- public enum TableNaming
- {
- Mixed = 0,
- Plural = 1,
- Singular = 2
- }
-
- public enum EntityNaming
- {
- Preserve = 0,
- Plural = 1,
- Singular = 2
- }
-
- public enum RelationshipNaming
- {
- None = 0,
- Plural = 1,
- ListSuffix = 2
- }
-
- public enum ContextNaming
- {
- Preserve = 0,
- Plural = 1,
- TableSuffix = 2
- }
-
- public class GeneratorSettings
- {
- public GeneratorSettings()
- {
- RelationshipNaming = RelationshipNaming.ListSuffix;
- EntityNaming = EntityNaming.Singular;
- TableNaming = TableNaming.Singular;
- CleanExpressions = new List { @"^\d+" };
- IgnoreExpressions = new List();
- }
-
- public TableNaming TableNaming { get; set; }
-
- public EntityNaming EntityNaming { get; set; }
-
- public RelationshipNaming RelationshipNaming { get; set; }
-
- public ContextNaming ContextNaming { get; set; }
-
- public List IgnoreExpressions { get; set; }
-
- public List CleanExpressions { get; set; }
-
- public bool InclusionMode { get; set; }
-
- public bool IsIgnored(string name)
- {
- if (IgnoreExpressions.Count == 0)
- return false;
-
- bool isMatch = IgnoreExpressions.Any(regex => Regex.IsMatch(name, regex));
-
- return InclusionMode ? !isMatch : isMatch;
- }
-
- public string CleanName(string name)
- {
- if (CleanExpressions.Count == 0)
- return name;
-
- foreach (var regex in CleanExpressions.Where(r => !string.IsNullOrEmpty(r)))
- if (Regex.IsMatch(name, regex))
- return Regex.Replace(name, regex, "");
-
- return name;
- }
-
- public string RelationshipName(string name)
- {
- if (RelationshipNaming == RelationshipNaming.None)
- return name;
-
- if (RelationshipNaming == RelationshipNaming.ListSuffix)
- return name + "List";
-
- return StringUtil.ToPascalCase(StringUtil.ToPlural(name));
- }
-
- public string ContextName(string name)
- {
- if (ContextNaming == ContextNaming.Preserve)
- return name;
-
- if (ContextNaming == ContextNaming.TableSuffix)
- return name + "Table";
-
- return StringUtil.ToPascalCase(StringUtil.ToPlural(name));
- }
-
- public string EntityName(string name)
- {
- if (TableNaming != TableNaming.Plural && EntityNaming == EntityNaming.Plural)
- name = StringUtil.ToPlural(name);
- else if (TableNaming != TableNaming.Singular && EntityNaming == EntityNaming.Singular)
- name = StringUtil.ToSingular(name);
-
- return StringUtil.ToPascalCase(name);
- }
- }
-
- public class SchemaItemProcessedEventArgs : EventArgs
- {
- public SchemaItemProcessedEventArgs(string name)
- {
- _name = name;
- }
-
- private readonly string _name;
- public string Name
- {
- get { return _name; }
- }
- }
-
- public class UniqueNamer
- {
- private readonly ConcurrentDictionary> _names;
-
- public UniqueNamer()
- {
- _names = new ConcurrentDictionary>(StringComparer.OrdinalIgnoreCase);
- Comparer = StringComparer.CurrentCulture;
-
- // add existing
- UniqueContextName("ChangeTracker");
- UniqueContextName("Configuration");
- UniqueContextName("Database");
- UniqueContextName("InternalContext");
- }
-
- public IEqualityComparer Comparer { get; set; }
-
- public string UniqueName(string bucketName, string name)
- {
- var hashSet = _names.GetOrAdd(bucketName, k => new HashSet(Comparer));
- string result = name.MakeUnique(hashSet.Contains);
- hashSet.Add(result);
-
- return result;
- }
-
- public string UniqueClassName(string className)
- {
- const string globalClassName = "global::ClassName";
- return UniqueName(globalClassName, className);
- }
-
- public string UniqueContextName(string name)
- {
- const string globalContextname = "global::ContextName";
- return UniqueName(globalContextname, name);
- }
-
- public string UniqueRelationshipName(string name)
- {
- const string globalContextname = "global::RelationshipName";
- return UniqueName(globalContextname, name);
- }
-
- }
-
- public class Generator
- {
- private readonly UniqueNamer _namer;
-
- public Generator()
- {
- _settings = new GeneratorSettings();
- _namer = new UniqueNamer();
- }
-
- public event EventHandler SchemaItemProcessed;
- protected void OnSchemaItemProcessed(string name)
- {
- var handler = SchemaItemProcessed;
- if (handler == null)
- return;
-
- handler(this, new SchemaItemProcessedEventArgs(name));
- }
-
- private readonly GeneratorSettings _settings;
- public GeneratorSettings Settings
- {
- get { return _settings; }
- }
-
- public EntityContext Generate(DatabaseSchema databaseSchema)
- {
- // only DeepLoad when in ignore mode
- databaseSchema.DeepLoad = !Settings.InclusionMode;
-
- var entityContext = new EntityContext();
- entityContext.DatabaseName = databaseSchema.Name;
-
- string dataContextName = StringUtil.ToPascalCase(databaseSchema.Name) + "Context";
- dataContextName = _namer.UniqueClassName(dataContextName);
-
- entityContext.ClassName = dataContextName;
-
- foreach (TableSchema t in databaseSchema.Tables)
- {
- if (Settings.IsIgnored(t.FullName))
- {
- Debug.WriteLine("Skipping Table: " + t.FullName);
- }
- else if (IsManyToMany(t))
- {
- CreateManyToMany(entityContext, t);
- }
- else
- {
- Debug.WriteLine("Getting Table Schema: " + t.FullName);
- GetEntity(entityContext, t);
- }
-
- OnSchemaItemProcessed(t.FullName);
- }
-
- return entityContext;
- }
-
-
- private Entity GetEntity(EntityContext entityContext, TableSchema tableSchema, bool processRelationships = true, bool processMethods = true)
- {
- string key = tableSchema.FullName;
-
- Entity entity = entityContext.Entities.ByTable(key)
- ?? CreateEntity(entityContext, tableSchema);
-
- if (!entity.Properties.IsProcessed)
- CreateProperties(entity, tableSchema);
-
- if (processRelationships && !entity.Relationships.IsProcessed)
- CreateRelationships(entityContext, entity, tableSchema);
-
- if (processMethods && !entity.Methods.IsProcessed)
- CreateMethods(entity, tableSchema);
-
- entity.IsProcessed = true;
- return entity;
- }
-
- private Entity CreateEntity(EntityContext entityContext, TableSchema tableSchema)
- {
- var entity = new Entity
- {
- FullName = tableSchema.FullName,
- TableName = tableSchema.Name,
- TableSchema = tableSchema.Owner,
- Description = tableSchema.Description
- };
-
- string className = ToClassName(tableSchema.Name);
- className = _namer.UniqueClassName(className);
-
- string mappingName = className + "Map";
- mappingName = _namer.UniqueClassName(mappingName);
-
- string contextName = Settings.ContextName(className);
- contextName = ToPropertyName(entityContext.ClassName, contextName);
- contextName = _namer.UniqueContextName(contextName);
-
- entity.ClassName = className;
- entity.ContextName = contextName;
- entity.MappingName = mappingName;
-
- entityContext.Entities.Add(entity);
-
- return entity;
- }
-
- ///
- /// 创建实体的属性
- ///
- private void CreateProperties(Entity entity, TableSchema tableSchema)
- {
- foreach (ColumnSchema columnSchema in tableSchema.Columns)
- {
- // skip unsupported type
- if (columnSchema.NativeType.Equals("hierarchyid", StringComparison.OrdinalIgnoreCase)
- || columnSchema.NativeType.Equals("sql_variant", StringComparison.OrdinalIgnoreCase))
- {
- Debug.WriteLine(string.Format("Skipping column '{0}' because it has an unsupported db type '{1}'.",
- columnSchema.Name, columnSchema.NativeType));
- continue;
- }
-
- Property property = entity.Properties.ByColumn(columnSchema.Name);
-
- if (property == null)
- {
- property = new Property { ColumnName = columnSchema.Name };
- entity.Properties.Add(property);
- }
-
- string propertyName = ToPropertyName(entity.ClassName, columnSchema.Name);
- propertyName = _namer.UniqueName(entity.ClassName, propertyName);
-
- property.PropertyName = propertyName;
-
- property.DataType = columnSchema.DataType;
- property.SystemType = columnSchema.SystemType;
- property.NativeType = columnSchema.NativeType;
- property.Description = columnSchema.Description;
-
- property.IsPrimaryKey = columnSchema.IsPrimaryKeyMember;
- property.IsForeignKey = columnSchema.IsForeignKeyMember;
- property.IsNullable = columnSchema.AllowDBNull;
-
- property.IsIdentity = IsIdentity(columnSchema);
- property.IsRowVersion = IsRowVersion(columnSchema);
- property.IsAutoGenerated = IsDbGenerated(columnSchema);
-
- if (columnSchema.IsUnique)
- property.IsUnique = columnSchema.IsUnique;
-
- if (property.SystemType == typeof(string)
- || property.SystemType == typeof(byte[]))
- {
- property.MaxLength = columnSchema.Size;
- }
-
- if (property.SystemType == typeof(float)
- || property.SystemType == typeof(double)
- || property.SystemType == typeof(decimal))
- {
- property.Precision = columnSchema.Precision;
- property.Scale = columnSchema.Scale;
- }
-
- property.IsProcessed = true;
- }
-
- entity.Properties.IsProcessed = true;
- }
-
-
- private void CreateRelationships(EntityContext entityContext, Entity entity, TableSchema tableSchema)
- {
- foreach (TableKeySchema tableKey in tableSchema.ForeignKeys)
- {
- if (Settings.IsIgnored(tableKey.ForeignKeyTable.FullName)
- || Settings.IsIgnored(tableKey.PrimaryKeyTable.FullName))
- {
- Debug.WriteLine("Skipping relationship '{0}' because table '{1}' or '{2}' is ignored.",
- tableKey.FullName, tableKey.ForeignKeyTable.FullName, tableKey.PrimaryKeyTable.FullName);
-
- continue;
- }
-
- CreateRelationship(entityContext, entity, tableKey);
- }
-
- entity.Relationships.IsProcessed = true;
- }
-
- private void CreateRelationship(EntityContext entityContext, Entity foreignEntity, TableKeySchema tableKeySchema)
- {
- Entity primaryEntity = GetEntity(entityContext, tableKeySchema.PrimaryKeyTable, false, false);
-
- string primaryName = primaryEntity.ClassName;
- string foreignName = foreignEntity.ClassName;
-
- string relationshipName = tableKeySchema.Name;
- relationshipName = _namer.UniqueRelationshipName(relationshipName);
-
- bool isCascadeDelete = IsCascadeDelete(tableKeySchema);
- bool foreignMembersRequired;
- bool primaryMembersRequired;
-
- var foreignMembers = GetKeyMembers(foreignEntity, tableKeySchema.ForeignKeyMemberColumns, tableKeySchema.Name, out foreignMembersRequired);
- var primaryMembers = GetKeyMembers(primaryEntity, tableKeySchema.PrimaryKeyMemberColumns, tableKeySchema.Name, out primaryMembersRequired);
-
- Relationship foreignRelationship = foreignEntity.Relationships
- .FirstOrDefault(r => r.RelationshipName == relationshipName && r.IsForeignKey);
-
- if (foreignRelationship == null)
- {
- foreignRelationship = new Relationship { RelationshipName = relationshipName };
- foreignEntity.Relationships.Add(foreignRelationship);
- }
- foreignRelationship.IsMapped = true;
- foreignRelationship.IsForeignKey = true;
- foreignRelationship.ThisCardinality = foreignMembersRequired ? Cardinality.One : Cardinality.ZeroOrOne;
- foreignRelationship.ThisEntity = foreignName;
- foreignRelationship.ThisProperties = new List(foreignMembers);
- foreignRelationship.OtherEntity = primaryName;
- foreignRelationship.OtherProperties = new List(primaryMembers);
- foreignRelationship.CascadeDelete = isCascadeDelete;
-
- string prefix = GetMemberPrefix(foreignRelationship, primaryName, foreignName);
-
- string foreignPropertyName = ToPropertyName(foreignEntity.ClassName, prefix + primaryName);
- foreignPropertyName = _namer.UniqueName(foreignEntity.ClassName, foreignPropertyName);
- foreignRelationship.ThisPropertyName = foreignPropertyName;
-
- // add reverse
- Relationship primaryRelationship = primaryEntity.Relationships
- .FirstOrDefault(r => r.RelationshipName == relationshipName && r.IsForeignKey == false);
-
- if (primaryRelationship == null)
- {
- primaryRelationship = new Relationship { RelationshipName = relationshipName };
- primaryEntity.Relationships.Add(primaryRelationship);
- }
-
- primaryRelationship.IsMapped = false;
- primaryRelationship.IsForeignKey = false;
- primaryRelationship.ThisEntity = primaryName;
- primaryRelationship.ThisProperties = new List(primaryMembers);
- primaryRelationship.OtherEntity = foreignName;
- primaryRelationship.OtherProperties = new List(foreignMembers);
- primaryRelationship.CascadeDelete = isCascadeDelete;
-
- bool isOneToOne = IsOneToOne(tableKeySchema, foreignRelationship);
-
- if (isOneToOne)
- primaryRelationship.ThisCardinality = primaryMembersRequired ? Cardinality.One : Cardinality.ZeroOrOne;
- else
- primaryRelationship.ThisCardinality = Cardinality.Many;
-
- string primaryPropertyName = prefix + foreignName;
- if (!isOneToOne)
- primaryPropertyName = Settings.RelationshipName(primaryPropertyName);
-
- primaryPropertyName = ToPropertyName(primaryEntity.ClassName, primaryPropertyName);
- primaryPropertyName = _namer.UniqueName(primaryEntity.ClassName, primaryPropertyName);
-
- primaryRelationship.ThisPropertyName = primaryPropertyName;
-
- foreignRelationship.OtherPropertyName = primaryRelationship.ThisPropertyName;
- foreignRelationship.OtherCardinality = primaryRelationship.ThisCardinality;
-
- primaryRelationship.OtherPropertyName = foreignRelationship.ThisPropertyName;
- primaryRelationship.OtherCardinality = foreignRelationship.ThisCardinality;
-
- foreignRelationship.IsProcessed = true;
- primaryRelationship.IsProcessed = true;
- }
-
- private void CreateManyToMany(EntityContext entityContext, TableSchema joinTable)
- {
- if (joinTable.ForeignKeys.Count != 2)
- return;
-
- var joinTableName = joinTable.Name;
- var joinSchemaName = joinTable.Owner;
-
- // first fkey is always left, second fkey is right
- var leftForeignKey = joinTable.ForeignKeys[0];
- var leftTable = leftForeignKey.PrimaryKeyTable;
- var joinLeftColumn = leftForeignKey.ForeignKeyMemberColumns.Select(c => c.Name).ToList();
- var leftEntity = GetEntity(entityContext, leftTable, false, false);
-
- var rightForeignKey = joinTable.ForeignKeys[1];
- var rightTable = rightForeignKey.PrimaryKeyTable;
- var joinRightColumn = rightForeignKey.ForeignKeyMemberColumns.Select(c => c.Name).ToList();
- var rightEntity = GetEntity(entityContext, rightTable, false, false);
-
- string leftPropertyName = Settings.RelationshipName(rightEntity.ClassName);
- leftPropertyName = _namer.UniqueName(leftEntity.ClassName, leftPropertyName);
-
- string rightPropertyName = Settings.RelationshipName(leftEntity.ClassName);
- rightPropertyName = _namer.UniqueName(rightEntity.ClassName, rightPropertyName);
-
- string relationshipName = string.Format("{0}|{1}",
- leftForeignKey.Name,
- rightForeignKey.Name);
-
- relationshipName = _namer.UniqueRelationshipName(relationshipName);
-
- var left = new Relationship { RelationshipName = relationshipName };
- left.IsForeignKey = false;
- left.IsMapped = true;
-
- left.ThisCardinality = Cardinality.Many;
- left.ThisEntity = leftEntity.ClassName;
- left.ThisPropertyName = leftPropertyName;
-
- left.OtherCardinality = Cardinality.Many;
- left.OtherEntity = rightEntity.ClassName;
- left.OtherPropertyName = rightPropertyName;
-
- left.JoinTable = joinTableName;
- left.JoinSchema = joinSchemaName;
- left.JoinThisColumn = new List(joinLeftColumn);
- left.JoinOtherColumn = new List(joinRightColumn);
-
- leftEntity.Relationships.Add(left);
-
- var right = new Relationship { RelationshipName = relationshipName };
- right.IsForeignKey = false;
- right.IsMapped = false;
-
- right.ThisCardinality = Cardinality.Many;
- right.ThisEntity = rightEntity.ClassName;
- right.ThisPropertyName = rightPropertyName;
-
- right.OtherCardinality = Cardinality.Many;
- right.OtherEntity = leftEntity.ClassName;
- right.OtherPropertyName = leftPropertyName;
-
- right.JoinTable = joinTableName;
- right.JoinSchema = joinSchemaName;
- right.JoinThisColumn = new List(joinRightColumn);
- right.JoinOtherColumn = new List(joinLeftColumn);
-
- rightEntity.Relationships.Add(right);
- }
-
-
- private void CreateMethods(Entity entity, TableSchema tableSchema)
- {
- if (tableSchema.HasPrimaryKey)
- {
- var method = GetMethodFromColumns(entity, tableSchema.PrimaryKey.MemberColumns);
- if (method != null)
- {
- method.IsKey = true;
- method.SourceName = tableSchema.PrimaryKey.FullName;
-
- if (!entity.Methods.Any(m => m.NameSuffix == method.NameSuffix))
- entity.Methods.Add(method);
- }
- }
-
- GetIndexMethods(entity, tableSchema);
- GetForeignKeyMethods(entity, tableSchema);
-
- entity.Methods.IsProcessed = true;
- }
-
- private static void GetForeignKeyMethods(Entity entity, TableSchema table)
- {
- var columns = new List();
-
- foreach (ColumnSchema column in table.ForeignKeyColumns)
- {
- columns.Add(column);
-
- Method method = GetMethodFromColumns(entity, columns);
- if (method != null && !entity.Methods.Any(m => m.NameSuffix == method.NameSuffix))
- entity.Methods.Add(method);
-
- columns.Clear();
- }
- }
-
- private static void GetIndexMethods(Entity entity, TableSchema table)
- {
- foreach (IndexSchema index in table.Indexes)
- {
- Method method = GetMethodFromColumns(entity, index.MemberColumns);
- if (method == null)
- continue;
-
- method.SourceName = index.FullName;
- method.IsUnique = index.IsUnique;
- method.IsIndex = true;
-
- if (!entity.Methods.Any(m => m.NameSuffix == method.NameSuffix))
- entity.Methods.Add(method);
- }
- }
-
- private static Method GetMethodFromColumns(Entity entity, IEnumerable columns)
- {
- var method = new Method();
- string methodName = string.Empty;
-
- foreach (var column in columns)
- {
- var property = entity.Properties.ByColumn(column.Name);
- if (property == null)
- continue;
-
- method.Properties.Add(property);
- methodName += property.PropertyName;
- }
-
- if (method.Properties.Count == 0)
- return null;
-
- method.NameSuffix = methodName;
- return method;
- }
-
-
- private static List GetKeyMembers(Entity entity, IEnumerable members, string name, out bool isRequired)
- {
- var keyMembers = new List();
- isRequired = false;
-
- foreach (var member in members)
- {
- var property = entity.Properties.ByColumn(member.Name);
-
- if (property == null)
- throw new InvalidOperationException(string.Format(
- "Could not find column {0} for relationship {1}.",
- member.Name,
- name));
-
- if (!isRequired)
- isRequired = property.IsRequired;
-
- keyMembers.Add(property.PropertyName);
- }
-
- return keyMembers;
- }
-
- private static string GetMemberPrefix(Relationship relationship, string primaryClass, string foreignClass)
- {
- string thisKey = relationship.ThisProperties.FirstOrDefault() ?? string.Empty;
- string otherKey = relationship.OtherProperties.FirstOrDefault() ?? string.Empty;
-
- bool isSameName = thisKey.Equals(otherKey, StringComparison.OrdinalIgnoreCase);
- isSameName = (isSameName || thisKey.Equals(primaryClass + otherKey, StringComparison.OrdinalIgnoreCase));
-
- string prefix = string.Empty;
- if (isSameName)
- return prefix;
-
- prefix = thisKey.Replace(otherKey, "");
- prefix = prefix.Replace(primaryClass, "");
- prefix = prefix.Replace(foreignClass, "");
- prefix = Regex.Replace(prefix, @"(_ID|_id|_Id|\.ID|\.id|\.Id|ID|Id)$", "");
- prefix = Regex.Replace(prefix, @"^\d", "");
-
- return prefix;
- }
-
- private static bool IsOneToOne(TableKeySchema tableKeySchema, Relationship foreignRelationship)
- {
- bool isFkeyPkey = tableKeySchema.ForeignKeyTable.HasPrimaryKey
- && tableKeySchema.ForeignKeyTable.PrimaryKey != null
- && tableKeySchema.ForeignKeyTable.PrimaryKey.MemberColumns.Count == 1
- && tableKeySchema.ForeignKeyTable.PrimaryKey.MemberColumns.Contains(
- foreignRelationship.ThisProperties.FirstOrDefault());
-
- if (isFkeyPkey)
- return true;
-
- // if f.key is unique
- return tableKeySchema.ForeignKeyMemberColumns.All(column => column.IsUnique);
- }
-
- private static bool IsManyToMany(TableSchema tableSchema)
- {
- // 1) Table must have Two ForeignKeys.
- // 2) All columns must be either...
- // a) Member of a Foreign Key.
- // b) DbGenerated
-
- if (tableSchema.Columns.Count < 2)
- return false;
-
- if (tableSchema.ForeignKeyColumns.Count != 2)
- return false;
-
- // all columns are fkeys
- if (tableSchema.Columns.Count == 2 &&
- tableSchema.ForeignKeyColumns.Count == 2)
- return true;
-
- // check all non fkey columns to make sure db gen'd
- return tableSchema.NonForeignKeyColumns.All(c =>
- IsDbGenerated(c) || HasDefaultValue(c));
- }
-
- #region Name Helpers
- private string ToClassName(string name)
- {
- name = Settings.EntityName(name);
- string legalName = ToLegalName(name);
-
- return legalName;
- }
-
- private string ToPropertyName(string className, string name)
- {
- string propertyName = ToLegalName(name);
- if (className.Equals(propertyName, StringComparison.OrdinalIgnoreCase))
- propertyName += "Member";
-
- return propertyName;
- }
-
- private string ToLegalName(string name)
- {
- string legalName = Settings.CleanName(name);
- legalName = StringUtil.ToPascalCase(legalName);
-
- return legalName;
- }
- #endregion
-
- #region Column Flag Helpers
- private static bool IsCascadeDelete(SchemaObjectBase column)
- {
- bool cascadeDelete = false;
- string value;
- try
- {
- if (column.ExtendedProperties.Contains(ExtendedPropertyNames.CascadeDelete))
- {
- value = column.ExtendedProperties[ExtendedPropertyNames.CascadeDelete].Value.ToString();
- bool.TryParse(value, out cascadeDelete);
- }
- }
- catch (Exception ex)
- {
- Debug.WriteLine("Error: " + ex.Message);
- }
-
- return cascadeDelete;
- }
-
- private static bool IsRowVersion(DataObjectBase column)
- {
- bool isTimeStamp = column.NativeType.Equals(
- "timestamp", StringComparison.OrdinalIgnoreCase);
- bool isRowVersion = column.NativeType.Equals(
- "rowversion", StringComparison.OrdinalIgnoreCase);
-
- return (isTimeStamp || isRowVersion);
- }
-
- private static bool IsDbGenerated(DataObjectBase column)
- {
- if (IsRowVersion(column))
- return true;
-
- if (IsIdentity(column))
- return true;
-
- bool isComputed = false;
- string value;
- try
- {
- if (column.ExtendedProperties.Contains(ExtendedPropertyNames.IsComputed))
- {
- value = column.ExtendedProperties[ExtendedPropertyNames.IsComputed].Value.ToString();
- bool.TryParse(value, out isComputed);
- }
- }
- catch (Exception ex)
- {
- Debug.WriteLine("Error: " + ex.Message);
- }
-
- return isComputed;
- }
-
- private static bool IsIdentity(DataObjectBase column)
- {
- string temp;
- bool isIdentity = false;
- try
- {
- if (column.ExtendedProperties.Contains(ExtendedPropertyNames.IsIdentity))
- {
- temp = column.ExtendedProperties[ExtendedPropertyNames.IsIdentity].Value.ToString();
- bool.TryParse(temp, out isIdentity);
- }
- }
- catch (Exception ex)
- {
- Debug.WriteLine("Error: " + ex.Message);
- }
-
- return isIdentity;
- }
-
- private static bool HasDefaultValue(DataObjectBase column)
- {
- try
- {
- if (!column.ExtendedProperties.Contains(ExtendedPropertyNames.DefaultValue))
- return false;
-
- string value = column.ExtendedProperties[ExtendedPropertyNames.DefaultValue].Value.ToString();
- return !string.IsNullOrEmpty(value);
- }
- catch (Exception ex)
- {
- Debug.WriteLine("Error: " + ex.Message);
- }
-
- return false;
- }
- #endregion
- }
-}
+using System;
+using System.Collections;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text.RegularExpressions;
+using CodeSmith.Engine;
+using SchemaExplorer;
+
+namespace SchemaMapper
+{
+ public enum TableNaming
+ {
+ Mixed = 0,
+ Plural = 1,
+ Singular = 2
+ }
+
+ public enum EntityNaming
+ {
+ Preserve = 0,
+ Plural = 1,
+ Singular = 2
+ }
+
+ public enum RelationshipNaming
+ {
+ None = 0,
+ Plural = 1,
+ ListSuffix = 2
+ }
+
+ public enum ContextNaming
+ {
+ Preserve = 0,
+ Plural = 1,
+ TableSuffix = 2
+ }
+
+ public class GeneratorSettings
+ {
+ public GeneratorSettings()
+ {
+ RelationshipNaming = RelationshipNaming.ListSuffix;
+ EntityNaming = EntityNaming.Singular;
+ TableNaming = TableNaming.Singular;
+ CleanExpressions = new List { @"^\d+" };
+ IgnoreExpressions = new List();
+ }
+
+ public TableNaming TableNaming { get; set; }
+
+ public EntityNaming EntityNaming { get; set; }
+
+ public RelationshipNaming RelationshipNaming { get; set; }
+
+ public ContextNaming ContextNaming { get; set; }
+
+ public List IgnoreExpressions { get; set; }
+
+ public List CleanExpressions { get; set; }
+
+ public bool InclusionMode { get; set; }
+
+ public bool IsIgnored(string name)
+ {
+ if (IgnoreExpressions.Count == 0)
+ return false;
+
+ bool isMatch = IgnoreExpressions.Any(regex => Regex.IsMatch(name, regex));
+
+ return InclusionMode ? !isMatch : isMatch;
+ }
+
+ public string CleanName(string name)
+ {
+ if (CleanExpressions.Count == 0)
+ return name;
+
+ foreach (var regex in CleanExpressions.Where(r => !string.IsNullOrEmpty(r)))
+ if (Regex.IsMatch(name, regex))
+ return Regex.Replace(name, regex, "");
+
+ return name;
+ }
+
+ public string RelationshipName(string name)
+ {
+ if (RelationshipNaming == RelationshipNaming.None)
+ return name;
+
+ if (RelationshipNaming == RelationshipNaming.ListSuffix)
+ return name + "List";
+
+ return StringUtil.ToPascalCase(StringUtil.ToPlural(name));
+ }
+
+ public string ContextName(string name)
+ {
+ if (ContextNaming == ContextNaming.Preserve)
+ return name;
+
+ if (ContextNaming == ContextNaming.TableSuffix)
+ return name + "Table";
+
+ return StringUtil.ToPascalCase(StringUtil.ToPlural(name));
+ }
+
+ public string EntityName(string name)
+ {
+ if (TableNaming != TableNaming.Plural && EntityNaming == EntityNaming.Plural)
+ name = StringUtil.ToPlural(name);
+ else if (TableNaming != TableNaming.Singular && EntityNaming == EntityNaming.Singular)
+ name = StringUtil.ToSingular(name);
+
+ return StringUtil.ToPascalCase(name);
+ }
+ }
+
+ public class SchemaItemProcessedEventArgs : EventArgs
+ {
+ public SchemaItemProcessedEventArgs(string name)
+ {
+ _name = name;
+ }
+
+ private readonly string _name;
+ public string Name
+ {
+ get { return _name; }
+ }
+ }
+
+ public class UniqueNamer
+ {
+ private readonly ConcurrentDictionary> _names;
+
+ public UniqueNamer()
+ {
+ _names = new ConcurrentDictionary>(StringComparer.OrdinalIgnoreCase);
+ Comparer = StringComparer.CurrentCulture;
+
+ // add existing
+ UniqueContextName("ChangeTracker");
+ UniqueContextName("Configuration");
+ UniqueContextName("Database");
+ UniqueContextName("InternalContext");
+ }
+
+ public IEqualityComparer Comparer { get; set; }
+
+ public string UniqueName(string bucketName, string name)
+ {
+ var hashSet = _names.GetOrAdd(bucketName, k => new HashSet(Comparer));
+ string result = name.MakeUnique(hashSet.Contains);
+ hashSet.Add(result);
+
+ return result;
+ }
+
+ public string UniqueClassName(string className)
+ {
+ const string globalClassName = "global::ClassName";
+ return UniqueName(globalClassName, className);
+ }
+
+ public string UniqueContextName(string name)
+ {
+ const string globalContextname = "global::ContextName";
+ return UniqueName(globalContextname, name);
+ }
+
+ public string UniqueRelationshipName(string name)
+ {
+ const string globalContextname = "global::RelationshipName";
+ return UniqueName(globalContextname, name);
+ }
+
+ }
+
+ public class Generator
+ {
+ private readonly UniqueNamer _namer;
+
+ public Generator()
+ {
+ _settings = new GeneratorSettings();
+ _namer = new UniqueNamer();
+ }
+
+ public event EventHandler SchemaItemProcessed;
+ protected void OnSchemaItemProcessed(string name)
+ {
+ var handler = SchemaItemProcessed;
+ if (handler == null)
+ return;
+
+ handler(this, new SchemaItemProcessedEventArgs(name));
+ }
+
+ private readonly GeneratorSettings _settings;
+ public GeneratorSettings Settings
+ {
+ get { return _settings; }
+ }
+
+ public EntityContext Generate(DatabaseSchema databaseSchema)
+ {
+ // only DeepLoad when in ignore mode
+ databaseSchema.DeepLoad = !Settings.InclusionMode;
+
+ var entityContext = new EntityContext();
+ entityContext.DatabaseName = databaseSchema.Name;
+
+ string dataContextName = StringUtil.ToPascalCase(databaseSchema.Name) + "Context";
+ dataContextName = _namer.UniqueClassName(dataContextName);
+
+ entityContext.ClassName = dataContextName;
+
+ foreach (TableSchema t in databaseSchema.Tables)
+ {
+ if (Settings.IsIgnored(t.FullName))
+ {
+ Debug.WriteLine("Skipping Table: " + t.FullName);
+ }
+ else if (IsManyToMany(t))
+ {
+ CreateManyToMany(entityContext, t);
+ }
+ else
+ {
+ Debug.WriteLine("Getting Table Schema: " + t.FullName);
+ GetEntity(entityContext, t);
+ }
+
+ OnSchemaItemProcessed(t.FullName);
+ }
+
+ return entityContext;
+ }
+
+
+ private Entity GetEntity(EntityContext entityContext, TableSchema tableSchema, bool processRelationships = true, bool processMethods = true)
+ {
+ string key = tableSchema.FullName;
+
+ Entity entity = entityContext.Entities.ByTable(key)
+ ?? CreateEntity(entityContext, tableSchema);
+
+ if (!entity.Properties.IsProcessed)
+ CreateProperties(entity, tableSchema);
+
+ if (processRelationships && !entity.Relationships.IsProcessed)
+ CreateRelationships(entityContext, entity, tableSchema);
+
+ if (processMethods && !entity.Methods.IsProcessed)
+ CreateMethods(entity, tableSchema);
+
+ entity.IsProcessed = true;
+ return entity;
+ }
+
+ private Entity CreateEntity(EntityContext entityContext, TableSchema tableSchema)
+ {
+ var entity = new Entity
+ {
+ FullName = tableSchema.FullName,
+ TableName = tableSchema.Name,
+ TableSchema = tableSchema.Owner,
+ Description = tableSchema.Description
+ };
+
+ string className = ToClassName(tableSchema.Name);
+ className = _namer.UniqueClassName(className);
+
+ string mappingName = className + "Map";
+ mappingName = _namer.UniqueClassName(mappingName);
+
+ string contextName = Settings.ContextName(className);
+ contextName = ToPropertyName(entityContext.ClassName, contextName);
+ contextName = _namer.UniqueContextName(contextName);
+
+ entity.ClassName = className;
+ entity.ContextName = contextName;
+ entity.MappingName = mappingName;
+
+ entityContext.Entities.Add(entity);
+
+ return entity;
+ }
+
+ ///
+ /// 创建实体的属性
+ ///
+ private void CreateProperties(Entity entity, TableSchema tableSchema)
+ {
+ foreach (ColumnSchema columnSchema in tableSchema.Columns)
+ {
+ // skip unsupported type
+ if (columnSchema.NativeType.Equals("hierarchyid", StringComparison.OrdinalIgnoreCase)
+ || columnSchema.NativeType.Equals("sql_variant", StringComparison.OrdinalIgnoreCase))
+ {
+ Debug.WriteLine(string.Format("Skipping column '{0}' because it has an unsupported db type '{1}'.",
+ columnSchema.Name, columnSchema.NativeType));
+ continue;
+ }
+
+ Property property = entity.Properties.ByColumn(columnSchema.Name);
+
+ if (property == null)
+ {
+ property = new Property { ColumnName = columnSchema.Name };
+ entity.Properties.Add(property);
+ }
+
+ string propertyName = ToPropertyName(entity.ClassName, columnSchema.Name);
+ propertyName = _namer.UniqueName(entity.ClassName, propertyName);
+
+ property.PropertyName = propertyName;
+
+ property.DataType = columnSchema.DataType;
+ property.SystemType = columnSchema.SystemType;
+ property.NativeType = columnSchema.NativeType;
+ property.Description = columnSchema.Description;
+
+ property.IsPrimaryKey = columnSchema.IsPrimaryKeyMember;
+ property.IsForeignKey = columnSchema.IsForeignKeyMember;
+ property.IsNullable = columnSchema.AllowDBNull;
+
+ property.IsIdentity = IsIdentity(columnSchema);
+ property.IsRowVersion = IsRowVersion(columnSchema);
+ property.IsAutoGenerated = IsDbGenerated(columnSchema);
+
+ if (columnSchema.IsUnique)
+ property.IsUnique = columnSchema.IsUnique;
+
+ if (property.SystemType == typeof(string)
+ || property.SystemType == typeof(byte[]))
+ {
+ property.MaxLength = columnSchema.Size;
+ }
+
+ if (property.SystemType == typeof(float)
+ || property.SystemType == typeof(double)
+ || property.SystemType == typeof(decimal))
+ {
+ property.Precision = columnSchema.Precision;
+ property.Scale = columnSchema.Scale;
+ }
+
+ property.IsProcessed = true;
+ }
+
+ entity.Properties.IsProcessed = true;
+ }
+
+
+ private void CreateRelationships(EntityContext entityContext, Entity entity, TableSchema tableSchema)
+ {
+ foreach (TableKeySchema tableKey in tableSchema.ForeignKeys)
+ {
+ if (Settings.IsIgnored(tableKey.ForeignKeyTable.FullName)
+ || Settings.IsIgnored(tableKey.PrimaryKeyTable.FullName))
+ {
+ Debug.WriteLine("Skipping relationship '{0}' because table '{1}' or '{2}' is ignored.",
+ tableKey.FullName, tableKey.ForeignKeyTable.FullName, tableKey.PrimaryKeyTable.FullName);
+
+ continue;
+ }
+
+ CreateRelationship(entityContext, entity, tableKey);
+ }
+
+ entity.Relationships.IsProcessed = true;
+ }
+
+ private void CreateRelationship(EntityContext entityContext, Entity foreignEntity, TableKeySchema tableKeySchema)
+ {
+ Entity primaryEntity = GetEntity(entityContext, tableKeySchema.PrimaryKeyTable, false, false);
+
+ string primaryName = primaryEntity.ClassName;
+ string foreignName = foreignEntity.ClassName;
+
+ string relationshipName = tableKeySchema.Name;
+ relationshipName = _namer.UniqueRelationshipName(relationshipName);
+
+ bool isCascadeDelete = IsCascadeDelete(tableKeySchema);
+ bool foreignMembersRequired;
+ bool primaryMembersRequired;
+
+ var foreignMembers = GetKeyMembers(foreignEntity, tableKeySchema.ForeignKeyMemberColumns, tableKeySchema.Name, out foreignMembersRequired);
+ var primaryMembers = GetKeyMembers(primaryEntity, tableKeySchema.PrimaryKeyMemberColumns, tableKeySchema.Name, out primaryMembersRequired);
+
+ Relationship foreignRelationship = foreignEntity.Relationships
+ .FirstOrDefault(r => r.RelationshipName == relationshipName && r.IsForeignKey);
+
+ if (foreignRelationship == null)
+ {
+ foreignRelationship = new Relationship { RelationshipName = relationshipName };
+ foreignEntity.Relationships.Add(foreignRelationship);
+ }
+ foreignRelationship.IsMapped = true;
+ foreignRelationship.IsForeignKey = true;
+ foreignRelationship.ThisCardinality = foreignMembersRequired ? Cardinality.One : Cardinality.ZeroOrOne;
+ foreignRelationship.ThisEntity = foreignName;
+ foreignRelationship.ThisProperties = new List(foreignMembers);
+ foreignRelationship.OtherEntity = primaryName;
+ foreignRelationship.OtherProperties = new List(primaryMembers);
+ foreignRelationship.CascadeDelete = isCascadeDelete;
+
+ string prefix = GetMemberPrefix(foreignRelationship, primaryName, foreignName);
+
+ string foreignPropertyName = ToPropertyName(foreignEntity.ClassName, prefix + primaryName);
+ foreignPropertyName = _namer.UniqueName(foreignEntity.ClassName, foreignPropertyName);
+ foreignRelationship.ThisPropertyName = foreignPropertyName;
+
+ // add reverse
+ Relationship primaryRelationship = primaryEntity.Relationships
+ .FirstOrDefault(r => r.RelationshipName == relationshipName && r.IsForeignKey == false);
+
+ if (primaryRelationship == null)
+ {
+ primaryRelationship = new Relationship { RelationshipName = relationshipName };
+ primaryEntity.Relationships.Add(primaryRelationship);
+ }
+
+ primaryRelationship.IsMapped = false;
+ primaryRelationship.IsForeignKey = false;
+ primaryRelationship.ThisEntity = primaryName;
+ primaryRelationship.ThisProperties = new List(primaryMembers);
+ primaryRelationship.OtherEntity = foreignName;
+ primaryRelationship.OtherProperties = new List(foreignMembers);
+ primaryRelationship.CascadeDelete = isCascadeDelete;
+
+ bool isOneToOne = IsOneToOne(tableKeySchema, foreignRelationship);
+
+ if (isOneToOne)
+ primaryRelationship.ThisCardinality = primaryMembersRequired ? Cardinality.One : Cardinality.ZeroOrOne;
+ else
+ primaryRelationship.ThisCardinality = Cardinality.Many;
+
+ string primaryPropertyName = prefix + foreignName;
+ if (!isOneToOne)
+ primaryPropertyName = Settings.RelationshipName(primaryPropertyName);
+
+ primaryPropertyName = ToPropertyName(primaryEntity.ClassName, primaryPropertyName);
+ primaryPropertyName = _namer.UniqueName(primaryEntity.ClassName, primaryPropertyName);
+
+ primaryRelationship.ThisPropertyName = primaryPropertyName;
+
+ foreignRelationship.OtherPropertyName = primaryRelationship.ThisPropertyName;
+ foreignRelationship.OtherCardinality = primaryRelationship.ThisCardinality;
+
+ primaryRelationship.OtherPropertyName = foreignRelationship.ThisPropertyName;
+ primaryRelationship.OtherCardinality = foreignRelationship.ThisCardinality;
+
+ foreignRelationship.IsProcessed = true;
+ primaryRelationship.IsProcessed = true;
+ }
+
+ private void CreateManyToMany(EntityContext entityContext, TableSchema joinTable)
+ {
+ if (joinTable.ForeignKeys.Count != 2)
+ return;
+
+ var joinTableName = joinTable.Name;
+ var joinSchemaName = joinTable.Owner;
+
+ // first fkey is always left, second fkey is right
+ var leftForeignKey = joinTable.ForeignKeys[0];
+ var leftTable = leftForeignKey.PrimaryKeyTable;
+ var joinLeftColumn = leftForeignKey.ForeignKeyMemberColumns.Select(c => c.Name).ToList();
+ var leftEntity = GetEntity(entityContext, leftTable, false, false);
+
+ var rightForeignKey = joinTable.ForeignKeys[1];
+ var rightTable = rightForeignKey.PrimaryKeyTable;
+ var joinRightColumn = rightForeignKey.ForeignKeyMemberColumns.Select(c => c.Name).ToList();
+ var rightEntity = GetEntity(entityContext, rightTable, false, false);
+
+ string leftPropertyName = Settings.RelationshipName(rightEntity.ClassName);
+ leftPropertyName = _namer.UniqueName(leftEntity.ClassName, leftPropertyName);
+
+ string rightPropertyName = Settings.RelationshipName(leftEntity.ClassName);
+ rightPropertyName = _namer.UniqueName(rightEntity.ClassName, rightPropertyName);
+
+ string relationshipName = string.Format("{0}|{1}",
+ leftForeignKey.Name,
+ rightForeignKey.Name);
+
+ relationshipName = _namer.UniqueRelationshipName(relationshipName);
+
+ var left = new Relationship { RelationshipName = relationshipName };
+ left.IsForeignKey = false;
+ left.IsMapped = true;
+
+ left.ThisCardinality = Cardinality.Many;
+ left.ThisEntity = leftEntity.ClassName;
+ left.ThisPropertyName = leftPropertyName;
+
+ left.OtherCardinality = Cardinality.Many;
+ left.OtherEntity = rightEntity.ClassName;
+ left.OtherPropertyName = rightPropertyName;
+
+ left.JoinTable = joinTableName;
+ left.JoinSchema = joinSchemaName;
+ left.JoinThisColumn = new List(joinLeftColumn);
+ left.JoinOtherColumn = new List(joinRightColumn);
+
+ leftEntity.Relationships.Add(left);
+
+ var right = new Relationship { RelationshipName = relationshipName };
+ right.IsForeignKey = false;
+ right.IsMapped = false;
+
+ right.ThisCardinality = Cardinality.Many;
+ right.ThisEntity = rightEntity.ClassName;
+ right.ThisPropertyName = rightPropertyName;
+
+ right.OtherCardinality = Cardinality.Many;
+ right.OtherEntity = leftEntity.ClassName;
+ right.OtherPropertyName = leftPropertyName;
+
+ right.JoinTable = joinTableName;
+ right.JoinSchema = joinSchemaName;
+ right.JoinThisColumn = new List(joinRightColumn);
+ right.JoinOtherColumn = new List(joinLeftColumn);
+
+ rightEntity.Relationships.Add(right);
+ }
+
+
+ private void CreateMethods(Entity entity, TableSchema tableSchema)
+ {
+ if (tableSchema.HasPrimaryKey)
+ {
+ var method = GetMethodFromColumns(entity, tableSchema.PrimaryKey.MemberColumns);
+ if (method != null)
+ {
+ method.IsKey = true;
+ method.SourceName = tableSchema.PrimaryKey.FullName;
+
+ if (!entity.Methods.Any(m => m.NameSuffix == method.NameSuffix))
+ entity.Methods.Add(method);
+ }
+ }
+
+ GetIndexMethods(entity, tableSchema);
+ GetForeignKeyMethods(entity, tableSchema);
+
+ entity.Methods.IsProcessed = true;
+ }
+
+ private static void GetForeignKeyMethods(Entity entity, TableSchema table)
+ {
+ var columns = new List();
+
+ foreach (ColumnSchema column in table.ForeignKeyColumns)
+ {
+ columns.Add(column);
+
+ Method method = GetMethodFromColumns(entity, columns);
+ if (method != null && !entity.Methods.Any(m => m.NameSuffix == method.NameSuffix))
+ entity.Methods.Add(method);
+
+ columns.Clear();
+ }
+ }
+
+ private static void GetIndexMethods(Entity entity, TableSchema table)
+ {
+ foreach (IndexSchema index in table.Indexes)
+ {
+ Method method = GetMethodFromColumns(entity, index.MemberColumns);
+ if (method == null)
+ continue;
+
+ method.SourceName = index.FullName;
+ method.IsUnique = index.IsUnique;
+ method.IsIndex = true;
+
+ if (!entity.Methods.Any(m => m.NameSuffix == method.NameSuffix))
+ entity.Methods.Add(method);
+ }
+ }
+
+ private static Method GetMethodFromColumns(Entity entity, IEnumerable columns)
+ {
+ var method = new Method();
+ string methodName = string.Empty;
+
+ foreach (var column in columns)
+ {
+ var property = entity.Properties.ByColumn(column.Name);
+ if (property == null)
+ continue;
+
+ method.Properties.Add(property);
+ methodName += property.PropertyName;
+ }
+
+ if (method.Properties.Count == 0)
+ return null;
+
+ method.NameSuffix = methodName;
+ return method;
+ }
+
+
+ private static List GetKeyMembers(Entity entity, IEnumerable members, string name, out bool isRequired)
+ {
+ var keyMembers = new List();
+ isRequired = false;
+
+ foreach (var member in members)
+ {
+ var property = entity.Properties.ByColumn(member.Name);
+
+ if (property == null)
+ throw new InvalidOperationException(string.Format(
+ "Could not find column {0} for relationship {1}.",
+ member.Name,
+ name));
+
+ if (!isRequired)
+ isRequired = property.IsRequired;
+
+ keyMembers.Add(property.PropertyName);
+ }
+
+ return keyMembers;
+ }
+
+ private static string GetMemberPrefix(Relationship relationship, string primaryClass, string foreignClass)
+ {
+ string thisKey = relationship.ThisProperties.FirstOrDefault() ?? string.Empty;
+ string otherKey = relationship.OtherProperties.FirstOrDefault() ?? string.Empty;
+
+ bool isSameName = thisKey.Equals(otherKey, StringComparison.OrdinalIgnoreCase);
+ isSameName = (isSameName || thisKey.Equals(primaryClass + otherKey, StringComparison.OrdinalIgnoreCase));
+
+ string prefix = string.Empty;
+ if (isSameName)
+ return prefix;
+
+ prefix = thisKey.Replace(otherKey, "");
+ prefix = prefix.Replace(primaryClass, "");
+ prefix = prefix.Replace(foreignClass, "");
+ prefix = Regex.Replace(prefix, @"(_ID|_id|_Id|\.ID|\.id|\.Id|ID|Id)$", "");
+ prefix = Regex.Replace(prefix, @"^\d", "");
+
+ return prefix;
+ }
+
+ private static bool IsOneToOne(TableKeySchema tableKeySchema, Relationship foreignRelationship)
+ {
+ bool isFkeyPkey = tableKeySchema.ForeignKeyTable.HasPrimaryKey
+ && tableKeySchema.ForeignKeyTable.PrimaryKey != null
+ && tableKeySchema.ForeignKeyTable.PrimaryKey.MemberColumns.Count == 1
+ && tableKeySchema.ForeignKeyTable.PrimaryKey.MemberColumns.Contains(
+ foreignRelationship.ThisProperties.FirstOrDefault());
+
+ if (isFkeyPkey)
+ return true;
+
+ // if f.key is unique
+ return tableKeySchema.ForeignKeyMemberColumns.All(column => column.IsUnique);
+ }
+
+ private static bool IsManyToMany(TableSchema tableSchema)
+ {
+ // 1) Table must have Two ForeignKeys.
+ // 2) All columns must be either...
+ // a) Member of a Foreign Key.
+ // b) DbGenerated
+
+ if (tableSchema.Columns.Count < 2)
+ return false;
+
+ if (tableSchema.ForeignKeyColumns.Count != 2)
+ return false;
+
+ // all columns are fkeys
+ if (tableSchema.Columns.Count == 2 &&
+ tableSchema.ForeignKeyColumns.Count == 2)
+ return true;
+
+ // check all non fkey columns to make sure db gen'd
+ return tableSchema.NonForeignKeyColumns.All(c =>
+ IsDbGenerated(c) || HasDefaultValue(c));
+ }
+
+ #region Name Helpers
+ private string ToClassName(string name)
+ {
+ name = Settings.EntityName(name);
+ string legalName = ToLegalName(name);
+
+ return legalName;
+ }
+
+ private string ToPropertyName(string className, string name)
+ {
+ string propertyName = ToLegalName(name);
+ if (className.Equals(propertyName, StringComparison.OrdinalIgnoreCase))
+ propertyName += "Member";
+
+ return propertyName;
+ }
+
+ private string ToLegalName(string name)
+ {
+ string legalName = Settings.CleanName(name);
+ legalName = StringUtil.ToPascalCase(legalName);
+
+ return legalName;
+ }
+ #endregion
+
+ #region Column Flag Helpers
+ private static bool IsCascadeDelete(SchemaObjectBase column)
+ {
+ bool cascadeDelete = false;
+ string value;
+ try
+ {
+ if (column.ExtendedProperties.Contains(ExtendedPropertyNames.CascadeDelete))
+ {
+ value = column.ExtendedProperties[ExtendedPropertyNames.CascadeDelete].Value.ToString();
+ bool.TryParse(value, out cascadeDelete);
+ }
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine("Error: " + ex.Message);
+ }
+
+ return cascadeDelete;
+ }
+
+ private static bool IsRowVersion(DataObjectBase column)
+ {
+ bool isTimeStamp = column.NativeType.Equals(
+ "timestamp", StringComparison.OrdinalIgnoreCase);
+ bool isRowVersion = column.NativeType.Equals(
+ "rowversion", StringComparison.OrdinalIgnoreCase);
+
+ return (isTimeStamp || isRowVersion);
+ }
+
+ private static bool IsDbGenerated(DataObjectBase column)
+ {
+ if (IsRowVersion(column))
+ return true;
+
+ if (IsIdentity(column))
+ return true;
+
+ bool isComputed = false;
+ string value;
+ try
+ {
+ if (column.ExtendedProperties.Contains(ExtendedPropertyNames.IsComputed))
+ {
+ value = column.ExtendedProperties[ExtendedPropertyNames.IsComputed].Value.ToString();
+ bool.TryParse(value, out isComputed);
+ }
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine("Error: " + ex.Message);
+ }
+
+ return isComputed;
+ }
+
+ private static bool IsIdentity(DataObjectBase column)
+ {
+ string temp;
+ bool isIdentity = false;
+ try
+ {
+ if (column.ExtendedProperties.Contains(ExtendedPropertyNames.IsIdentity))
+ {
+ temp = column.ExtendedProperties[ExtendedPropertyNames.IsIdentity].Value.ToString();
+ bool.TryParse(temp, out isIdentity);
+ }
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine("Error: " + ex.Message);
+ }
+
+ return isIdentity;
+ }
+
+ private static bool HasDefaultValue(DataObjectBase column)
+ {
+ try
+ {
+ if (!column.ExtendedProperties.Contains(ExtendedPropertyNames.DefaultValue))
+ return false;
+
+ string value = column.ExtendedProperties[ExtendedPropertyNames.DefaultValue].Value.ToString();
+ return !string.IsNullOrEmpty(value);
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine("Error: " + ex.Message);
+ }
+
+ return false;
+ }
+ #endregion
+ }
+}
diff --git a/CodeSmith/CSharp/Internal/Mapping.Generated.cst b/CodeSmith/CSharp/Internal/Mapping.Generated.cst
index ed4136fd..8d59b7fd 100644
--- a/CodeSmith/CSharp/Internal/Mapping.Generated.cst
+++ b/CodeSmith/CSharp/Internal/Mapping.Generated.cst
@@ -1,294 +1,294 @@
-<%@ Template Language="C#" TargetLanguage="C#" Debug="True" Encoding="UTF-8" %>
-
-<%@ Assembly Src="Model.cs" %>
-<%@ Assembly Src="Extensions.cs" %>
-
-<%@ Import Namespace="System.Collections.Generic" %>
-<%@ Import Namespace="System.Linq" %>
-<%@ Import Namespace="System.Text" %>
-<%@ Import Namespace="System.Text.RegularExpressions" %>
-
-<%@ Import Namespace="SchemaMapper" %>
-
-<%@ Property Name="Entity" Type="SchemaMapper.Entity" %>
-<%@ Property Name="ContextNamespace" Type="System.String" %>
-<%@ Property Name="EntityNamespace" Type="System.String" %>
-<%@ Property Name="MappingNamespace" Type="System.String" %>
-//------------------------------------------------------------------------------
-//
-// This code was generated by a CodeSmith Template.
-//
-// DO NOT MODIFY contents of this file. Changes to this
-// file will be lost if the code is regenerated.
-//
-//------------------------------------------------------------------------------
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations;
-
-namespace <%= MappingNamespace %>
-{
- public partial class <%= Entity.MappingName.ToSafeName() %>
- : System.Data.Entity.ModelConfiguration.EntityTypeConfiguration<<%= EntityNamespace %>.<%= Entity.ClassName.ToSafeName() %>>
- {
- public <%= Entity.MappingName.ToSafeName() %>()
- {
- // table
-<% if (string.IsNullOrEmpty(Entity.TableSchema)) { %>
- ToTable("<%= Entity.TableName %>");
-<% } else { %>
- ToTable("<%= Entity.TableName %>", "<%= Entity.TableSchema %>");
-<% } %>
-
- // keys
-<% if (Entity.Properties.PrimaryKeys.Count() > 0) { %>
- HasKey(t => <%= KeyExpression(Entity.Properties.PrimaryKeys, "t") %>);
-<% } %>
-
- // Properties
-<%
-foreach(var p in Entity.Properties)
-{
- Response.Write(PropertyExpression(p));
-}
-%>
-
- // Relationships
-<%
-foreach(var r in Entity.Relationships.Where(e => e.IsMapped))
-{
- if (r.IsManyToMany)
- Response.Write(ManyToManyExpression(r));
- else
- Response.Write(RelationshipExpression(r));
-}
-%>
- }
- }
-}
-
-
\ No newline at end of file
diff --git a/CodeSmith/CSharp/Internal/Model.cs b/CodeSmith/CSharp/Internal/Model.cs
index b7b2a6f1..f8d51e06 100644
--- a/CodeSmith/CSharp/Internal/Model.cs
+++ b/CodeSmith/CSharp/Internal/Model.cs
@@ -1,370 +1,370 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Data;
-using System.Diagnostics;
-using System.Linq;
-using System.Xml.Serialization;
-
-namespace SchemaMapper
-{
- #region Base
- public enum Cardinality
- {
- ZeroOrOne,
- One,
- Many
- }
-
- public class EntityBase
- {
- [XmlIgnore]
- public bool IsProcessed { get; set; }
- }
- #endregion
-
- #region Model
- [DebuggerDisplay("Context: {ContextName}, Database: {DatabaseName}")]
- public class EntityContext : EntityBase
- {
- public EntityContext()
- {
- Entities = new EntityCollection();
- }
-
- public string ClassName { get; set; }
- public string DatabaseName { get; set; }
-
- public EntityCollection Entities { get; set; }
-
- public void RenameEntity(string originalName, string newName)
- {
- if (originalName == newName)
- return;
-
- Debug.WriteLine("Rename Entity '{0}' to '{1}'.", originalName, newName);
- foreach (var entity in Entities)
- {
- if (entity.ClassName == originalName)
- entity.ClassName = newName;
-
- foreach (var relationship in entity.Relationships)
- {
- if (relationship.ThisEntity == originalName)
- relationship.ThisEntity = newName;
- if (relationship.OtherEntity == originalName)
- relationship.OtherEntity = newName;
- }
- }
- }
-
- public void RenameProperty(string entityName, string originalName, string newName)
- {
- if (originalName == newName)
- return;
-
- Debug.WriteLine("Rename Property '{0}' to '{1}' in Entity '{2}'.", originalName, newName, entityName);
- foreach (var entity in Entities)
- {
- if (entity.ClassName == entityName)
- {
- var property = entity.Properties.ByProperty(originalName);
- if (property != null)
- property.PropertyName = newName;
- }
-
- foreach (var relationship in entity.Relationships)
- {
- if (relationship.ThisEntity == entityName)
- for (int i = 0; i < relationship.ThisProperties.Count; i++)
- if (relationship.ThisProperties[i] == originalName)
- relationship.ThisProperties[i] = newName;
-
- if (relationship.OtherEntity == entityName)
- for (int i = 0; i < relationship.OtherProperties.Count; i++)
- if (relationship.OtherProperties[i] == originalName)
- relationship.OtherProperties[i] = newName;
- }
- }
-
- }
- }
-
- [DebuggerDisplay("Class: {ClassName}, Table: {FullName}, Context: {ContextName}")]
- public class Entity : EntityBase
- {
- public Entity()
- {
- Properties = new PropertyCollection();
- Relationships = new RelationshipCollection();
- Methods = new MethodCollection();
- }
-
- public string ContextName { get; set; }
- public string ClassName { get; set; }
- public string MappingName { get; set; }
- public string Description{ get;set;}
-
- public string TableSchema { get; set; }
- public string TableName { get; set; }
- public string FullName { get; set; }
-
- public PropertyCollection Properties { get; set; }
- public RelationshipCollection Relationships { get; set; }
- public MethodCollection Methods { get; set; }
- }
-
- [DebuggerDisplay("Property: {PropertyName}, Column: {ColumnName}, Type: {NativeType}")]
- public class Property : EntityBase
- {
- public string PropertyName { get; set; }
- public string ColumnName { get; set; }
- public string Description { get; set; }
-
- public DbType DataType { get; set; }
- public string NativeType { get; set; }
-
- [XmlIgnore]
- public Type SystemType { get; set; }
-
- public int? Order { get; set; }
- public bool OrderSpecified
- {
- get { return Order.HasValue; }
- }
-
- public bool? IsNullable { get; set; }
- public bool IsNullableSpecified
- {
- get { return IsNullable.HasValue; }
- }
-
- public bool IsRequired
- {
- get { return IsNullable == false; }
- set { IsNullable = !value; }
- }
- public bool IsOptional
- {
- get { return IsNullable == true; }
- set { IsNullable = value; }
- }
-
- public bool? IsPrimaryKey { get; set; }
- public bool IsPrimaryKeySpecified
- {
- get { return IsPrimaryKey.HasValue; }
- }
- public bool? IsForeignKey { get; set; }
- public bool IsForeignKeySpecified
- {
- get { return IsForeignKey.HasValue; }
- }
-
- public bool? IsAutoGenerated { get; set; }
- public bool IsAutoGeneratedSpecified
- {
- get { return IsAutoGenerated.HasValue; }
- }
- public bool? IsReadOnly { get; set; }
- public bool IsReadOnlySpecified
- {
- get { return IsReadOnly.HasValue; }
- }
- public bool? IsRowVersion { get; set; }
- public bool IsRowVersionSpecified
- {
- get { return IsRowVersion.HasValue; }
- }
- public bool? IsIdentity { get; set; }
- public bool IsIdentitySpecified
- {
- get { return IsIdentity.HasValue; }
- }
- public bool? IsUnique { get; set; }
- public bool IsUniqueSpecified
- {
- get { return IsUnique.HasValue; }
- }
-
- public bool? IsUnicode { get; set; }
- public bool IsUnicodeSpecified
- {
- get { return IsUnicode.HasValue; }
- }
- public bool? IsFixedLength { get; set; }
- public bool IsFixedLengthSpecified
- {
- get { return IsFixedLength.HasValue; }
- }
-
- public int? MaxLength { get; set; }
- public bool MaxLengthSpecified
- {
- get { return MaxLength.HasValue; }
- }
-
- public byte? Precision { get; set; }
- public bool PrecisionSpecified
- {
- get { return Precision.HasValue; }
- }
- public int? Scale { get; set; }
- public bool ScaleSpecified
- {
- get { return Scale.HasValue; }
- }
- }
-
- [DebuggerDisplay("Other: {OtherEntity}, Property: {OtherPropertyName}, Relationship: {RelationshipName}")]
- public class Relationship : EntityBase
- {
- public Relationship()
- {
- OtherProperties = new List();
- ThisProperties = new List();
- }
-
- public string RelationshipName { get; set; }
-
- public string ThisEntity { get; set; }
- public string ThisPropertyName { get; set; }
- public Cardinality ThisCardinality { get; set; }
- public List ThisProperties { get; set; }
-
- public string OtherEntity { get; set; }
- public string OtherPropertyName { get; set; }
- public Cardinality OtherCardinality { get; set; }
- public List OtherProperties { get; set; }
-
- public bool? CascadeDelete { get; set; }
- public bool IsForeignKey { get; set; }
- public bool IsMapped { get; set; }
-
- public bool IsManyToMany
- {
- get
- {
- return ThisCardinality == Cardinality.Many
- && OtherCardinality == Cardinality.Many;
- }
- }
-
- public bool IsOneToOne
- {
- get
- {
- return ThisCardinality != Cardinality.Many
- && OtherCardinality != Cardinality.Many;
- }
- }
-
- public string JoinTable { get; set; }
- public string JoinSchema { get; set; }
- public List JoinThisColumn { get; set; }
- public List JoinOtherColumn { get; set; }
-
- }
-
- [DebuggerDisplay("Suffix: {NameSuffix}, IsKey: {IsKey}, IsUnique: {IsUnique}")]
- public class Method : EntityBase
- {
- public Method()
- {
- Properties = new List();
- }
-
- public string NameSuffix { get; set; }
- public string SourceName { get; set; }
-
- public bool IsKey { get; set; }
- public bool IsUnique { get; set; }
- public bool IsIndex { get; set; }
-
- public List Properties { get; set; }
- }
- #endregion
-
- #region Collections
- public class EntityCollection
- : ObservableCollection
- {
- public bool IsProcessed { get; set; }
-
- public Entity ByTable(string fullName)
- {
- return this.FirstOrDefault(x => x.FullName == fullName);
- }
-
- public Entity ByTable(string tableName, string tableSchema)
- {
- return this.FirstOrDefault(x => x.TableName == tableName && x.TableSchema == tableSchema);
- }
-
- public Entity ByClass(string className)
- {
- return this.FirstOrDefault(x => x.ClassName == className);
- }
-
- public Entity ByContext(string contextName)
- {
- return this.FirstOrDefault(x => x.ContextName == contextName);
- }
- }
-
- public class PropertyCollection
- : ObservableCollection
- {
- public bool IsProcessed { get; set; }
-
- public IEnumerable PrimaryKeys
- {
- get { return this.Where(p => p.IsPrimaryKey == true); }
- }
-
- public IEnumerable ForeignKeys
- {
- get { return this.Where(p => p.IsForeignKey == true); }
- }
-
- public Property ByColumn(string columnName)
- {
- return this.FirstOrDefault(x => x.ColumnName == columnName);
- }
-
- public Property ByProperty(string propertyName)
- {
- return this.FirstOrDefault(x => x.PropertyName == propertyName);
- }
- }
-
- public class RelationshipCollection
- : ObservableCollection
- {
- public bool IsProcessed { get; set; }
-
- public Relationship ByName(string name)
- {
- return this.FirstOrDefault(x => x.RelationshipName == name);
- }
-
- public Relationship ByProperty(string propertyName)
- {
- return this.FirstOrDefault(x => x.ThisPropertyName == propertyName);
- }
-
- public Relationship ByOther(string name)
- {
- return this.FirstOrDefault(x => x.OtherEntity == name);
- }
- }
-
- public class MethodCollection
- : ObservableCollection
- {
- public bool IsProcessed { get; set; }
- }
-
- #endregion
-}
-
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Data;
+using System.Diagnostics;
+using System.Linq;
+using System.Xml.Serialization;
+
+namespace SchemaMapper
+{
+ #region Base
+ public enum Cardinality
+ {
+ ZeroOrOne,
+ One,
+ Many
+ }
+
+ public class EntityBase
+ {
+ [XmlIgnore]
+ public bool IsProcessed { get; set; }
+ }
+ #endregion
+
+ #region Model
+ [DebuggerDisplay("Context: {ContextName}, Database: {DatabaseName}")]
+ public class EntityContext : EntityBase
+ {
+ public EntityContext()
+ {
+ Entities = new EntityCollection();
+ }
+
+ public string ClassName { get; set; }
+ public string DatabaseName { get; set; }
+
+ public EntityCollection Entities { get; set; }
+
+ public void RenameEntity(string originalName, string newName)
+ {
+ if (originalName == newName)
+ return;
+
+ Debug.WriteLine("Rename Entity '{0}' to '{1}'.", originalName, newName);
+ foreach (var entity in Entities)
+ {
+ if (entity.ClassName == originalName)
+ entity.ClassName = newName;
+
+ foreach (var relationship in entity.Relationships)
+ {
+ if (relationship.ThisEntity == originalName)
+ relationship.ThisEntity = newName;
+ if (relationship.OtherEntity == originalName)
+ relationship.OtherEntity = newName;
+ }
+ }
+ }
+
+ public void RenameProperty(string entityName, string originalName, string newName)
+ {
+ if (originalName == newName)
+ return;
+
+ Debug.WriteLine("Rename Property '{0}' to '{1}' in Entity '{2}'.", originalName, newName, entityName);
+ foreach (var entity in Entities)
+ {
+ if (entity.ClassName == entityName)
+ {
+ var property = entity.Properties.ByProperty(originalName);
+ if (property != null)
+ property.PropertyName = newName;
+ }
+
+ foreach (var relationship in entity.Relationships)
+ {
+ if (relationship.ThisEntity == entityName)
+ for (int i = 0; i < relationship.ThisProperties.Count; i++)
+ if (relationship.ThisProperties[i] == originalName)
+ relationship.ThisProperties[i] = newName;
+
+ if (relationship.OtherEntity == entityName)
+ for (int i = 0; i < relationship.OtherProperties.Count; i++)
+ if (relationship.OtherProperties[i] == originalName)
+ relationship.OtherProperties[i] = newName;
+ }
+ }
+
+ }
+ }
+
+ [DebuggerDisplay("Class: {ClassName}, Table: {FullName}, Context: {ContextName}")]
+ public class Entity : EntityBase
+ {
+ public Entity()
+ {
+ Properties = new PropertyCollection();
+ Relationships = new RelationshipCollection();
+ Methods = new MethodCollection();
+ }
+
+ public string ContextName { get; set; }
+ public string ClassName { get; set; }
+ public string MappingName { get; set; }
+ public string Description{ get;set;}
+
+ public string TableSchema { get; set; }
+ public string TableName { get; set; }
+ public string FullName { get; set; }
+
+ public PropertyCollection Properties { get; set; }
+ public RelationshipCollection Relationships { get; set; }
+ public MethodCollection Methods { get; set; }
+ }
+
+ [DebuggerDisplay("Property: {PropertyName}, Column: {ColumnName}, Type: {NativeType}")]
+ public class Property : EntityBase
+ {
+ public string PropertyName { get; set; }
+ public string ColumnName { get; set; }
+ public string Description { get; set; }
+
+ public DbType DataType { get; set; }
+ public string NativeType { get; set; }
+
+ [XmlIgnore]
+ public Type SystemType { get; set; }
+
+ public int? Order { get; set; }
+ public bool OrderSpecified
+ {
+ get { return Order.HasValue; }
+ }
+
+ public bool? IsNullable { get; set; }
+ public bool IsNullableSpecified
+ {
+ get { return IsNullable.HasValue; }
+ }
+
+ public bool IsRequired
+ {
+ get { return IsNullable == false; }
+ set { IsNullable = !value; }
+ }
+ public bool IsOptional
+ {
+ get { return IsNullable == true; }
+ set { IsNullable = value; }
+ }
+
+ public bool? IsPrimaryKey { get; set; }
+ public bool IsPrimaryKeySpecified
+ {
+ get { return IsPrimaryKey.HasValue; }
+ }
+ public bool? IsForeignKey { get; set; }
+ public bool IsForeignKeySpecified
+ {
+ get { return IsForeignKey.HasValue; }
+ }
+
+ public bool? IsAutoGenerated { get; set; }
+ public bool IsAutoGeneratedSpecified
+ {
+ get { return IsAutoGenerated.HasValue; }
+ }
+ public bool? IsReadOnly { get; set; }
+ public bool IsReadOnlySpecified
+ {
+ get { return IsReadOnly.HasValue; }
+ }
+ public bool? IsRowVersion { get; set; }
+ public bool IsRowVersionSpecified
+ {
+ get { return IsRowVersion.HasValue; }
+ }
+ public bool? IsIdentity { get; set; }
+ public bool IsIdentitySpecified
+ {
+ get { return IsIdentity.HasValue; }
+ }
+ public bool? IsUnique { get; set; }
+ public bool IsUniqueSpecified
+ {
+ get { return IsUnique.HasValue; }
+ }
+
+ public bool? IsUnicode { get; set; }
+ public bool IsUnicodeSpecified
+ {
+ get { return IsUnicode.HasValue; }
+ }
+ public bool? IsFixedLength { get; set; }
+ public bool IsFixedLengthSpecified
+ {
+ get { return IsFixedLength.HasValue; }
+ }
+
+ public int? MaxLength { get; set; }
+ public bool MaxLengthSpecified
+ {
+ get { return MaxLength.HasValue; }
+ }
+
+ public byte? Precision { get; set; }
+ public bool PrecisionSpecified
+ {
+ get { return Precision.HasValue; }
+ }
+ public int? Scale { get; set; }
+ public bool ScaleSpecified
+ {
+ get { return Scale.HasValue; }
+ }
+ }
+
+ [DebuggerDisplay("Other: {OtherEntity}, Property: {OtherPropertyName}, Relationship: {RelationshipName}")]
+ public class Relationship : EntityBase
+ {
+ public Relationship()
+ {
+ OtherProperties = new List();
+ ThisProperties = new List();
+ }
+
+ public string RelationshipName { get; set; }
+
+ public string ThisEntity { get; set; }
+ public string ThisPropertyName { get; set; }
+ public Cardinality ThisCardinality { get; set; }
+ public List ThisProperties { get; set; }
+
+ public string OtherEntity { get; set; }
+ public string OtherPropertyName { get; set; }
+ public Cardinality OtherCardinality { get; set; }
+ public List OtherProperties { get; set; }
+
+ public bool? CascadeDelete { get; set; }
+ public bool IsForeignKey { get; set; }
+ public bool IsMapped { get; set; }
+
+ public bool IsManyToMany
+ {
+ get
+ {
+ return ThisCardinality == Cardinality.Many
+ && OtherCardinality == Cardinality.Many;
+ }
+ }
+
+ public bool IsOneToOne
+ {
+ get
+ {
+ return ThisCardinality != Cardinality.Many
+ && OtherCardinality != Cardinality.Many;
+ }
+ }
+
+ public string JoinTable { get; set; }
+ public string JoinSchema { get; set; }
+ public List JoinThisColumn { get; set; }
+ public List JoinOtherColumn { get; set; }
+
+ }
+
+ [DebuggerDisplay("Suffix: {NameSuffix}, IsKey: {IsKey}, IsUnique: {IsUnique}")]
+ public class Method : EntityBase
+ {
+ public Method()
+ {
+ Properties = new List();
+ }
+
+ public string NameSuffix { get; set; }
+ public string SourceName { get; set; }
+
+ public bool IsKey { get; set; }
+ public bool IsUnique { get; set; }
+ public bool IsIndex { get; set; }
+
+ public List Properties { get; set; }
+ }
+ #endregion
+
+ #region Collections
+ public class EntityCollection
+ : ObservableCollection
+ {
+ public bool IsProcessed { get; set; }
+
+ public Entity ByTable(string fullName)
+ {
+ return this.FirstOrDefault(x => x.FullName == fullName);
+ }
+
+ public Entity ByTable(string tableName, string tableSchema)
+ {
+ return this.FirstOrDefault(x => x.TableName == tableName && x.TableSchema == tableSchema);
+ }
+
+ public Entity ByClass(string className)
+ {
+ return this.FirstOrDefault(x => x.ClassName == className);
+ }
+
+ public Entity ByContext(string contextName)
+ {
+ return this.FirstOrDefault(x => x.ContextName == contextName);
+ }
+ }
+
+ public class PropertyCollection
+ : ObservableCollection
+ {
+ public bool IsProcessed { get; set; }
+
+ public IEnumerable PrimaryKeys
+ {
+ get { return this.Where(p => p.IsPrimaryKey == true); }
+ }
+
+ public IEnumerable ForeignKeys
+ {
+ get { return this.Where(p => p.IsForeignKey == true); }
+ }
+
+ public Property ByColumn(string columnName)
+ {
+ return this.FirstOrDefault(x => x.ColumnName == columnName);
+ }
+
+ public Property ByProperty(string propertyName)
+ {
+ return this.FirstOrDefault(x => x.PropertyName == propertyName);
+ }
+ }
+
+ public class RelationshipCollection
+ : ObservableCollection
+ {
+ public bool IsProcessed { get; set; }
+
+ public Relationship ByName(string name)
+ {
+ return this.FirstOrDefault(x => x.RelationshipName == name);
+ }
+
+ public Relationship ByProperty(string propertyName)
+ {
+ return this.FirstOrDefault(x => x.ThisPropertyName == propertyName);
+ }
+
+ public Relationship ByOther(string name)
+ {
+ return this.FirstOrDefault(x => x.OtherEntity == name);
+ }
+ }
+
+ public class MethodCollection
+ : ObservableCollection
+ {
+ public bool IsProcessed { get; set; }
+ }
+
+ #endregion
+}
+
diff --git a/CodeSmith/CSharp/Internal/Parser.cs b/CodeSmith/CSharp/Internal/Parser.cs
index 95766be9..fcc8ae56 100644
--- a/CodeSmith/CSharp/Internal/Parser.cs
+++ b/CodeSmith/CSharp/Internal/Parser.cs
@@ -1,639 +1,639 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using System.Text;
-using ICSharpCode.NRefactory.CSharp;
-
-namespace SchemaMapper
-{
- #region Mapping Parser
- [DebuggerDisplay("Table: {TableName}, Entity: {EntityClass}, Mapping: {MappingClass}")]
- public class ParsedEntity
- {
- public ParsedEntity()
- {
- Properties = new List();
- Relationships = new List();
- }
-
- public string EntityClass { get; set; }
- public string MappingClass { get; set; }
-
- public string TableName { get; set; }
- public string TableSchema { get; set; }
-
- public List Properties { get; private set; }
- public List Relationships { get; private set; }
- }
-
- [DebuggerDisplay("Column: {ColumnName}, Property: {PropertyName}")]
- public class ParsedProperty
- {
- public string ColumnName { get; set; }
- public string PropertyName { get; set; }
- }
-
- [DebuggerDisplay("This: {ThisPropertyName}, Other: {OtherPropertyName}")]
- public class ParsedRelationship
- {
- public ParsedRelationship()
- {
- ThisProperties = new List();
- JoinThisColumn = new List();
- JoinOtherColumn = new List();
- }
-
- public string ThisPropertyName { get; set; }
- public List ThisProperties { get; private set; }
-
- public string OtherPropertyName { get; set; }
-
- public string JoinTable { get; set; }
- public string JoinSchema { get; set; }
- public List JoinThisColumn { get; private set; }
- public List JoinOtherColumn { get; private set; }
- }
-
- public class MappingVisitor : DepthFirstAstVisitor