| 
0
 | 
     1 <#
 | 
| 
 | 
     2 	ConnectionType = typeof(System.Data.SqlClient.SqlConnection).AssemblyQualifiedName;
 | 
| 
 | 
     3 #><#+
 | 
| 
 | 
     4 private void LoadServerMetadata()
 | 
| 
 | 
     5 {
 | 
| 
 | 
     6 	var tables  = CreateList(new { ID = "", Table  = new Table() });
 | 
| 
 | 
     7 	var columns = CreateList(new { ID = "", Column = new Column() });
 | 
| 
 | 
     8 
 | 
| 
 | 
     9 	using (var conn = GetConnection())
 | 
| 
 | 
    10 	using (var cmd  = conn.CreateCommand())
 | 
| 
 | 
    11 	{
 | 
| 
 | 
    12 		// Load tables & views.
 | 
| 
 | 
    13 		//
 | 
| 
 | 
    14 		string s = @"
 | 
| 
 | 
    15 			SELECT
 | 
| 
 | 
    16 				TABLE_CATALOG + '.' + TABLE_SCHEMA + '.' + TABLE_NAME AS TABLE_FULLNAME,
 | 
| 
 | 
    17 				TABLE_SCHEMA,
 | 
| 
 | 
    18 				TABLE_NAME,
 | 
| 
 | 
    19 				TABLE_TYPE,
 | 
| 
 | 
    20 				ISNULL(CONVERT(varchar(8000), x.Value), '') AS TABLE_DESC
 | 
| 
 | 
    21 			FROM
 | 
| 
 | 
    22 				INFORMATION_SCHEMA.TABLES s
 | 
| 
 | 
    23 				LEFT JOIN 
 | 
| 
 | 
    24 					sys.tables t 
 | 
| 
 | 
    25 				ON 
 | 
| 
 | 
    26 					OBJECT_ID(TABLE_CATALOG + '.' + TABLE_SCHEMA + '.' + TABLE_NAME) = t.object_id
 | 
| 
 | 
    27 				LEFT JOIN 
 | 
| 
 | 
    28 					sys.extended_properties x 
 | 
| 
 | 
    29 				ON 
 | 
| 
 | 
    30 					OBJECT_ID(TABLE_CATALOG + '.' + TABLE_SCHEMA + '.' + TABLE_NAME) = x.major_id AND 
 | 
| 
 | 
    31 					x.minor_id = 0 AND 
 | 
| 
 | 
    32 					x.name = 'MS_Description'
 | 
| 
 | 
    33 			WHERE {0}
 | 
| 
 | 
    34 			(
 | 
| 
 | 
    35 				t.object_id IS NULL OR
 | 
| 
 | 
    36 				t.is_ms_shipped <> 1 AND
 | 
| 
 | 
    37 				(
 | 
| 
 | 
    38 					SELECT 
 | 
| 
 | 
    39 						major_id 
 | 
| 
 | 
    40 					FROM 
 | 
| 
 | 
    41 						sys.extended_properties 
 | 
| 
 | 
    42 					WHERE
 | 
| 
 | 
    43 						major_id = t.object_id and 
 | 
| 
 | 
    44 						minor_id = 0           and 
 | 
| 
 | 
    45 						class    = 1           and 
 | 
| 
 | 
    46 						name     = N'microsoft_database_tools_support'
 | 
| 
 | 
    47 					) IS NULL
 | 
| 
 | 
    48 			)";
 | 
| 
 | 
    49 
 | 
| 
 | 
    50 		if (string.IsNullOrWhiteSpace(OwnerToInclude))
 | 
| 
 | 
    51 			cmd.CommandText = string.Format(s, "");
 | 
| 
 | 
    52 		else
 | 
| 
 | 
    53 			cmd.CommandText = string.Format(s, " TABLE_SCHEMA = '" + OwnerToInclude + "' AND ");
 | 
| 
 | 
    54 
 | 
| 
 | 
    55 		using (var rd = cmd.ExecuteReader())
 | 
| 
 | 
    56 		{
 | 
| 
 | 
    57 			while (rd.Read())
 | 
| 
 | 
    58 			{
 | 
| 
 | 
    59 				var t = new
 | 
| 
 | 
    60 				{
 | 
| 
 | 
    61 					ID    = Convert.ToString(rd[0]),
 | 
| 
 | 
    62 					Table = new Table
 | 
| 
 | 
    63 					{
 | 
| 
 | 
    64 						Owner         = rd[1].ToString(),
 | 
| 
 | 
    65 						TableName     = rd[2].ToString(),
 | 
| 
 | 
    66 						ClassName     = rd[2].ToString(),
 | 
| 
 | 
    67 						IsView        = rd[3].ToString() == "VIEW",
 | 
| 
 | 
    68 						BaseClassName = BaseEntityClass,
 | 
| 
 | 
    69 						Description   = Convert.ToString(rd[4]),
 | 
| 
 | 
    70 					}
 | 
| 
 | 
    71 				};
 | 
| 
 | 
    72 
 | 
| 
 | 
    73 				tables.Add(t);
 | 
| 
 | 
    74 			}
 | 
| 
 | 
    75 		}
 | 
| 
 | 
    76 
 | 
| 
 | 
    77 		// Load columns.
 | 
| 
 | 
    78 		//
 | 
| 
 | 
    79 		s = @"
 | 
| 
 | 
    80 			SELECT
 | 
| 
 | 
    81 				(TABLE_CATALOG + '.' + TABLE_SCHEMA + '.' + TABLE_NAME) as id,
 | 
| 
 | 
    82 				(CASE WHEN IS_NULLABLE = 'YES' THEN 1 ELSE 0 END)         as isNullable,
 | 
| 
 | 
    83 				ORDINAL_POSITION         as colid,
 | 
| 
 | 
    84 				COLUMN_NAME              as name,
 | 
| 
 | 
    85 				c.DATA_TYPE              as dataType,
 | 
| 
 | 
    86 				CHARACTER_MAXIMUM_LENGTH as length, 
 | 
| 
 | 
    87 				ISNULL(NUMERIC_PRECISION, DATETIME_PRECISION) AS prec,
 | 
| 
 | 
    88 				NUMERIC_SCALE            as scale,
 | 
| 
 | 
    89 				COLUMNPROPERTY(object_id('[' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']'), COLUMN_NAME, 'IsIdentity') as isIdentity,
 | 
| 
 | 
    90 				ISNULL(CONVERT(varchar(8000), x.Value), '') AS COLUMN_DESC
 | 
| 
 | 
    91 			FROM
 | 
| 
 | 
    92 				INFORMATION_SCHEMA.COLUMNS c
 | 
| 
 | 
    93 			  LEFT JOIN 
 | 
| 
 | 
    94 				sys.extended_properties x 
 | 
| 
 | 
    95 			  ON 
 | 
| 
 | 
    96 				OBJECT_ID(TABLE_CATALOG + '.' + TABLE_SCHEMA + '.' + TABLE_NAME) = x.major_id AND 
 | 
| 
 | 
    97 				ORDINAL_POSITION = x.minor_id AND 
 | 
| 
 | 
    98 				x.name = 'MS_Description'
 | 
| 
 | 
    99 			{0}";
 | 
| 
 | 
   100 
 | 
| 
 | 
   101 		if(string.IsNullOrWhiteSpace(OwnerToInclude))
 | 
| 
 | 
   102 			cmd.CommandText = string.Format(s, "");
 | 
| 
 | 
   103 		else
 | 
| 
 | 
   104 			cmd.CommandText = string.Format(s, "WHERE TABLE_SCHEMA = '" + OwnerToInclude + "' ");
 | 
| 
 | 
   105 
 | 
| 
 | 
   106 		using (var rd = cmd.ExecuteReader())
 | 
| 
 | 
   107 		{
 | 
| 
 | 
   108 			while (rd.Read())
 | 
| 
 | 
   109 			{
 | 
| 
 | 
   110 				var col = new
 | 
| 
 | 
   111 				{
 | 
| 
 | 
   112 					ID     = Convert.ToString(rd["id"]),
 | 
| 
 | 
   113 					Column = new Column
 | 
| 
 | 
   114 					{
 | 
| 
 | 
   115 						ID         = Convert.ToInt16  (rd["colid"]),
 | 
| 
 | 
   116 						ColumnName = Convert.ToString (rd["name"]),
 | 
| 
 | 
   117 						MemberName = Convert.ToString (rd["name"]),
 | 
| 
 | 
   118 						ColumnType = Convert.ToString (rd["dataType"]),
 | 
| 
 | 
   119 						IsNullable = Convert.ToBoolean(rd["isNullable"]),
 | 
| 
 | 
   120 						IsIdentity = Convert.ToBoolean(rd["isIdentity"]),
 | 
| 
 | 
   121 						Length     = rd.IsDBNull(rd.GetOrdinal("length")) ? 0 : Convert.ToInt64(rd["length"]),
 | 
| 
 | 
   122 						Precision  = rd.IsDBNull(rd.GetOrdinal("prec"))   ? 0 : Convert.ToInt32(rd["prec"]),
 | 
| 
 | 
   123 						Scale      = rd.IsDBNull(rd.GetOrdinal("scale"))  ? 0 : Convert.ToInt32(rd["scale"]),
 | 
| 
 | 
   124 						Description = Convert.ToString(rd["COLUMN_DESC"]),
 | 
| 
 | 
   125 					}
 | 
| 
 | 
   126 				};
 | 
| 
 | 
   127 
 | 
| 
 | 
   128 				var c = col.Column;
 | 
| 
 | 
   129 
 | 
| 
 | 
   130 				switch (c.ColumnType)
 | 
| 
 | 
   131 				{
 | 
| 
 | 
   132 					case "image"            : c.Type = "byte[]";         c.DbType = DbType.Binary;         c.SqlDbType = SqlDbType.Image;            break;
 | 
| 
 | 
   133 					case "text"             : c.Type = "string";         c.DbType = DbType.String;         c.SqlDbType = SqlDbType.Text;             break;
 | 
| 
 | 
   134 					case "binary"           : c.Type = "byte[]";         c.DbType = DbType.Binary;         c.SqlDbType = SqlDbType.Binary;           break;
 | 
| 
 | 
   135 					case "tinyint"          : c.Type = "byte";           c.DbType = DbType.Byte;           c.SqlDbType = SqlDbType.TinyInt;          break;
 | 
| 
 | 
   136 					case "date"             : c.Type = "DateTime";       c.DbType = DbType.Date;           c.SqlDbType = SqlDbType.Date;             break;
 | 
| 
 | 
   137 					case "time"             : c.Type = "DateTime";       c.DbType = DbType.Time;           c.SqlDbType = SqlDbType.Time;             break;
 | 
| 
 | 
   138 					case "bit"              : c.Type = "bool";           c.DbType = DbType.Boolean;        c.SqlDbType = SqlDbType.Bit;              break;
 | 
| 
 | 
   139 					case "smallint"         : c.Type = "short";          c.DbType = DbType.Int16;          c.SqlDbType = SqlDbType.SmallInt;         break;
 | 
| 
 | 
   140 					case "decimal"          : c.Type = "decimal";        c.DbType = DbType.Decimal;        c.SqlDbType = SqlDbType.Decimal;          break;
 | 
| 
 | 
   141 					case "int"              : c.Type = "int";            c.DbType = DbType.Int32;          c.SqlDbType = SqlDbType.Int;              break;
 | 
| 
 | 
   142 					case "smalldatetime"    : c.Type = "DateTime";       c.DbType = DbType.DateTime;       c.SqlDbType = SqlDbType.SmallDateTime;    break;
 | 
| 
 | 
   143 					case "real"             : c.Type = "float";          c.DbType = DbType.Single;         c.SqlDbType = SqlDbType.Real;             break;
 | 
| 
 | 
   144 					case "money"            : c.Type = "decimal";        c.DbType = DbType.Currency;       c.SqlDbType = SqlDbType.Money;            break;
 | 
| 
 | 
   145 					case "datetime"         : c.Type = "DateTime";       c.DbType = DbType.DateTime;       c.SqlDbType = SqlDbType.DateTime;         break;
 | 
| 
 | 
   146 					case "float"            : c.Type = "double";         c.DbType = DbType.Double;         c.SqlDbType = SqlDbType.Float;            break;
 | 
| 
 | 
   147 					case "numeric"          : c.Type = "decimal";        c.DbType = DbType.Decimal;        c.SqlDbType = SqlDbType.Decimal;          break;
 | 
| 
 | 
   148 					case "smallmoney"       : c.Type = "decimal";        c.DbType = DbType.Currency;       c.SqlDbType = SqlDbType.SmallMoney;       break;
 | 
| 
 | 
   149 					case "datetime2"        : c.Type = "DateTime";       c.DbType = DbType.DateTime2;      c.SqlDbType = SqlDbType.DateTime2;        break;
 | 
| 
 | 
   150 					case "bigint"           : c.Type = "long";           c.DbType = DbType.Int64;          c.SqlDbType = SqlDbType.BigInt;           break;
 | 
| 
 | 
   151 					case "varbinary"        : c.Type = "byte[]";         c.DbType = DbType.Binary;         c.SqlDbType = SqlDbType.VarBinary;        break;
 | 
| 
 | 
   152 					case "timestamp"        : c.Type = "byte[]";         c.DbType = DbType.Binary;         c.SqlDbType = SqlDbType.Timestamp;        break;
 | 
| 
 | 
   153 					case "sysname"          : c.Type = "string";         c.DbType = DbType.String;         c.SqlDbType = SqlDbType.NVarChar;         break;
 | 
| 
 | 
   154 					case "nvarchar"         : c.Type = "string";         c.DbType = DbType.String;         c.SqlDbType = SqlDbType.NVarChar;         break;
 | 
| 
 | 
   155 					case "varchar"          : c.Type = "string";         c.DbType = DbType.AnsiString;     c.SqlDbType = SqlDbType.VarChar;          break;
 | 
| 
 | 
   156 					case "ntext"            : c.Type = "string";         c.DbType = DbType.String;         c.SqlDbType = SqlDbType.NText;            break;
 | 
| 
 | 
   157 					case "uniqueidentifier" : c.Type = "Guid";           c.DbType = DbType.Binary;         c.SqlDbType = SqlDbType.UniqueIdentifier; break;
 | 
| 
 | 
   158 					case "datetimeoffset"   : c.Type = "DateTimeOffset"; c.DbType = DbType.DateTimeOffset; c.SqlDbType = SqlDbType.DateTimeOffset;   break;
 | 
| 
 | 
   159 					case "sql_variant"      : c.Type = "object";         c.DbType = DbType.Binary;         c.SqlDbType = SqlDbType.Variant;          break;
 | 
| 
 | 
   160 					case "xml"              : c.Type = "string";         c.DbType = DbType.Xml;            c.SqlDbType = SqlDbType.Xml;              break;
 | 
| 
 | 
   161 
 | 
| 
 | 
   162 					case "char" :
 | 
| 
 | 
   163 						c.Type      = Convert.ToInt32 (rd["length"]) == 1 ? "char" : "string";
 | 
| 
 | 
   164 						c.DbType    = DbType.AnsiStringFixedLength;
 | 
| 
 | 
   165 						c.SqlDbType = SqlDbType.Char;
 | 
| 
 | 
   166 						break;
 | 
| 
 | 
   167 
 | 
| 
 | 
   168 					case "nchar" :
 | 
| 
 | 
   169 						c.Type      = Convert.ToInt32 (rd["length"]) == 1 ? "char" : "string";
 | 
| 
 | 
   170 						c.DbType    = DbType.StringFixedLength;
 | 
| 
 | 
   171 						c.SqlDbType = SqlDbType.NChar;
 | 
| 
 | 
   172 						break;
 | 
| 
 | 
   173 
 | 
| 
 | 
   174 					//hierarchyid
 | 
| 
 | 
   175 					//geometry
 | 
| 
 | 
   176 					//geography
 | 
| 
 | 
   177 					default                 : c.Type = "byte[]";         c.DbType = DbType.Binary;         c.SqlDbType = SqlDbType.Binary;           break;
 | 
| 
 | 
   178 				}
 | 
| 
 | 
   179 
 | 
| 
 | 
   180 				switch (c.Type)
 | 
| 
 | 
   181 				{
 | 
| 
 | 
   182 					case "string" :
 | 
| 
 | 
   183 					case "object" :
 | 
| 
 | 
   184 					case "byte[]" : c.IsClass = true; break;
 | 
| 
 | 
   185 				}
 | 
| 
 | 
   186 
 | 
| 
 | 
   187 				if (c.IsNullable && !c.IsClass)
 | 
| 
 | 
   188 					c.Type += "?";
 | 
| 
 | 
   189 
 | 
| 
 | 
   190 				columns.Add(col);
 | 
| 
 | 
   191 			}
 | 
| 
 | 
   192 		}
 | 
| 
 | 
   193 
 | 
| 
 | 
   194 		// Load PKs.
 | 
| 
 | 
   195 		//
 | 
| 
 | 
   196 		s = @"
 | 
| 
 | 
   197 			SELECT
 | 
| 
 | 
   198 				(k.TABLE_CATALOG + '.' + k.TABLE_SCHEMA + '.' + k.TABLE_NAME) as id,
 | 
| 
 | 
   199 				k.CONSTRAINT_NAME                                             as name,
 | 
| 
 | 
   200 				k.COLUMN_NAME                                                 as colname,
 | 
| 
 | 
   201 				k.ORDINAL_POSITION                                            as colid
 | 
| 
 | 
   202 			FROM
 | 
| 
 | 
   203 				INFORMATION_SCHEMA.KEY_COLUMN_USAGE k
 | 
| 
 | 
   204 			  JOIN 
 | 
| 
 | 
   205 				INFORMATION_SCHEMA.TABLE_CONSTRAINTS c 
 | 
| 
 | 
   206 			  ON 
 | 
| 
 | 
   207 				k.CONSTRAINT_CATALOG = c.CONSTRAINT_CATALOG AND 
 | 
| 
 | 
   208 				k.CONSTRAINT_SCHEMA = c.CONSTRAINT_SCHEMA AND 
 | 
| 
 | 
   209 				k.CONSTRAINT_NAME = c.CONSTRAINT_NAME
 | 
| 
 | 
   210 			WHERE
 | 
| 
 | 
   211 				c.CONSTRAINT_TYPE='PRIMARY KEY' 
 | 
| 
 | 
   212 				{0}";
 | 
| 
 | 
   213 
 | 
| 
 | 
   214 		if (string.IsNullOrWhiteSpace(OwnerToInclude))
 | 
| 
 | 
   215 			cmd.CommandText = string.Format(s, "");
 | 
| 
 | 
   216 		else
 | 
| 
 | 
   217 			cmd.CommandText = string.Format(s, "AND k.TABLE_SCHEMA = '" + OwnerToInclude + "' ");
 | 
| 
 | 
   218 
 | 
| 
 | 
   219 		using (var rd = cmd.ExecuteReader())
 | 
| 
 | 
   220 		{
 | 
| 
 | 
   221 			while (rd.Read())
 | 
| 
 | 
   222 			{
 | 
| 
 | 
   223 				var id      = Convert.ToString(rd["id"]);
 | 
| 
 | 
   224 				var colid   = Convert.ToInt32 (rd["colid"]);
 | 
| 
 | 
   225 				var colname = Convert.ToString(rd["colname"]);
 | 
| 
 | 
   226 
 | 
| 
 | 
   227 				columns.Single(_ => _.ID == id && _.Column.ColumnName == colname).Column.PKIndex = colid;
 | 
| 
 | 
   228 			}
 | 
| 
 | 
   229 		}
 | 
| 
 | 
   230 
 | 
| 
 | 
   231 		// Load FKs.
 | 
| 
 | 
   232 		//
 | 
| 
 | 
   233 		s = @"
 | 
| 
 | 
   234 			SELECT
 | 
| 
 | 
   235 				rc.CONSTRAINT_NAME  as Name, 
 | 
| 
 | 
   236 				fk.TABLE_CATALOG + '.' + fk.TABLE_SCHEMA + '.' + fk.TABLE_NAME as ThisTable,
 | 
| 
 | 
   237 				fk.COLUMN_NAME      as ThisColumn,
 | 
| 
 | 
   238 				pk.TABLE_CATALOG + '.' + pk.TABLE_SCHEMA + '.' + pk.TABLE_NAME as OtherTable,
 | 
| 
 | 
   239 				pk.COLUMN_NAME      as OtherColumn,
 | 
| 
 | 
   240 				cu.ORDINAL_POSITION as Ordinal
 | 
| 
 | 
   241 			FROM
 | 
| 
 | 
   242 				INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc
 | 
| 
 | 
   243 			  JOIN 
 | 
| 
 | 
   244 				INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE fk
 | 
| 
 | 
   245 					ON
 | 
| 
 | 
   246 						rc.CONSTRAINT_CATALOG        = fk.CONSTRAINT_CATALOG AND
 | 
| 
 | 
   247 				rc.CONSTRAINT_SCHEMA		 = fk.CONSTRAINT_SCHEMA AND
 | 
| 
 | 
   248 						rc.CONSTRAINT_NAME           = fk.CONSTRAINT_NAME
 | 
| 
 | 
   249 			  JOIN 
 | 
| 
 | 
   250 				INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE pk
 | 
| 
 | 
   251 					ON
 | 
| 
 | 
   252 						rc.UNIQUE_CONSTRAINT_CATALOG = pk.CONSTRAINT_CATALOG AND
 | 
| 
 | 
   253 				rc.UNIQUE_CONSTRAINT_SCHEMA	 = pk.CONSTRAINT_SCHEMA AND
 | 
| 
 | 
   254 						rc.UNIQUE_CONSTRAINT_NAME    = pk.CONSTRAINT_NAME
 | 
| 
 | 
   255 			  JOIN 
 | 
| 
 | 
   256 				INFORMATION_SCHEMA.KEY_COLUMN_USAGE cu
 | 
| 
 | 
   257 					ON
 | 
| 
 | 
   258 				rc.CONSTRAINT_CATALOG = cu.CONSTRAINT_CATALOG AND
 | 
| 
 | 
   259 				rc.CONSTRAINT_SCHEMA = cu.CONSTRAINT_SCHEMA AND
 | 
| 
 | 
   260 						rc.CONSTRAINT_NAME = cu.CONSTRAINT_NAME
 | 
| 
 | 
   261 			{0}
 | 
| 
 | 
   262 			ORDER BY
 | 
| 
 | 
   263 				ThisTable,
 | 
| 
 | 
   264 				Ordinal";
 | 
| 
 | 
   265 
 | 
| 
 | 
   266 		if (string.IsNullOrWhiteSpace(OwnerToInclude))
 | 
| 
 | 
   267 			cmd.CommandText = string.Format(s, "");
 | 
| 
 | 
   268 		else
 | 
| 
 | 
   269 			cmd.CommandText = string.Format(s, "WHERE fk.TABLE_SCHEMA = '" + OwnerToInclude + "' ");
 | 
| 
 | 
   270 
 | 
| 
 | 
   271 		using (var rd = cmd.ExecuteReader())
 | 
| 
 | 
   272 		{
 | 
| 
 | 
   273 			while (rd.Read())
 | 
| 
 | 
   274 			{
 | 
| 
 | 
   275 				var name            = Convert.ToString(rd["Name"]);
 | 
| 
 | 
   276 				var thisTableID     = Convert.ToString(rd["ThisTable"]);
 | 
| 
 | 
   277 				var otherTableID    = Convert.ToString(rd["OtherTable"]);
 | 
| 
 | 
   278 				var thisColumnName  = Convert.ToString(rd["ThisColumn"]);
 | 
| 
 | 
   279 				var otherColumnName = Convert.ToString(rd["OtherColumn"]);
 | 
| 
 | 
   280 
 | 
| 
 | 
   281 				var thisTable   = (from t in tables  where t.ID == thisTableID  select t.Table).Single();
 | 
| 
 | 
   282 				var otherTable  = (from t in tables  where t.ID == otherTableID select t.Table).Single();
 | 
| 
 | 
   283 				var thisColumn  = (from c in columns where c.ID == thisTableID  && c.Column.ColumnName == thisColumnName  select c.Column).Single();
 | 
| 
 | 
   284 				var otherColumn = (from c in columns where c.ID == otherTableID && c.Column.ColumnName == otherColumnName select c.Column).Single();
 | 
| 
 | 
   285 
 | 
| 
 | 
   286 				if (thisTable.ForeignKeys.ContainsKey(name) == false)
 | 
| 
 | 
   287 					thisTable.ForeignKeys.Add(name, new ForeignKey { KeyName = name, MemberName = name, OtherTable = otherTable });
 | 
| 
 | 
   288 
 | 
| 
 | 
   289 				var key = thisTable.ForeignKeys[name];
 | 
| 
 | 
   290 
 | 
| 
 | 
   291 				key.ThisColumns. Add(thisColumn);
 | 
| 
 | 
   292 				key.OtherColumns.Add(otherColumn);
 | 
| 
 | 
   293 			}
 | 
| 
 | 
   294 		}
 | 
| 
 | 
   295 	}
 | 
| 
 | 
   296 
 | 
| 
 | 
   297 	var qc =
 | 
| 
 | 
   298 		from c in columns
 | 
| 
 | 
   299 		group c by c.ID into gr
 | 
| 
 | 
   300 		join t in tables on gr.Key equals t.ID
 | 
| 
 | 
   301 		select new { t.Table, gr };
 | 
| 
 | 
   302 
 | 
| 
 | 
   303 	foreach (var c in qc)
 | 
| 
 | 
   304 	{
 | 
| 
 | 
   305 		foreach (var col in from col in c.gr orderby col.Column.ID select col.Column)
 | 
| 
 | 
   306 			c.Table.Columns.Add(col.ColumnName, col);
 | 
| 
 | 
   307 
 | 
| 
 | 
   308 		if (c.Table.Owner == "dbo")
 | 
| 
 | 
   309 		{
 | 
| 
 | 
   310 			c.Table.Owner = null;
 | 
| 
 | 
   311 			Tables.Add(c.Table.TableName, c.Table);
 | 
| 
 | 
   312 		}
 | 
| 
 | 
   313 		else
 | 
| 
 | 
   314 		{
 | 
| 
 | 
   315 			Tables.Add(c.Table.Owner + "." + c.Table.TableName, c.Table);
 | 
| 
 | 
   316 		}
 | 
| 
 | 
   317 	}
 | 
| 
 | 
   318 
 | 
| 
 | 
   319 	{
 | 
| 
 | 
   320 		Usings.Add("System.Collections.Generic");
 | 
| 
 | 
   321 		Usings.Add("System.Linq");
 | 
| 
 | 
   322 		Usings.Add("System.Linq.Expressions");
 | 
| 
 | 
   323 		Usings.Add("System.Reflection");
 | 
| 
 | 
   324 		Usings.Add("System.Text");
 | 
| 
 | 
   325 		Usings.Add("BLToolkit.Data.DataProvider");
 | 
| 
 | 
   326 		Usings.Add("BLToolkit.Data.Sql");
 | 
| 
 | 
   327 		Usings.Add("BLToolkit.Data.Sql.SqlProvider");
 | 
| 
 | 
   328 
 | 
| 
 | 
   329 		var mssqlAfterWriteTableProperty = AfterWriteTableProperty;
 | 
| 
 | 
   330 
 | 
| 
 | 
   331 		AfterWriteTableProperty = tt =>
 | 
| 
 | 
   332 		{
 | 
| 
 | 
   333 			mssqlAfterWriteTableProperty(tt);
 | 
| 
 | 
   334 
 | 
| 
 | 
   335 			tt.WriteLine(@"
 | 
| 
 | 
   336 #region FreeTextTable
 | 
| 
 | 
   337 
 | 
| 
 | 
   338 public class FreeTextKey<T>
 | 
| 
 | 
   339 {
 | 
| 
 | 
   340 	public T   Key;
 | 
| 
 | 
   341 	public int Rank;
 | 
| 
 | 
   342 }
 | 
| 
 | 
   343 
 | 
| 
 | 
   344 class FreeTextTableExpressionAttribute : TableExpressionAttribute
 | 
| 
 | 
   345 {
 | 
| 
 | 
   346 	public FreeTextTableExpressionAttribute()
 | 
| 
 | 
   347 		: base("""")
 | 
| 
 | 
   348 	{
 | 
| 
 | 
   349 	}
 | 
| 
 | 
   350 
 | 
| 
 | 
   351 	public override void SetTable(SqlTable table, MemberInfo member, IEnumerable<Expression> expArgs, IEnumerable<ISqlExpression> sqlArgs)
 | 
| 
 | 
   352 	{
 | 
| 
 | 
   353 		var aargs  = sqlArgs.ToArray();
 | 
| 
 | 
   354 		var arr    = ConvertArgs(member, aargs).ToList();
 | 
| 
 | 
   355 		var method = (MethodInfo)member;
 | 
| 
 | 
   356 		var sp     = new MsSql2008SqlProvider();
 | 
| 
 | 
   357 
 | 
| 
 | 
   358 		{
 | 
| 
 | 
   359 			var ttype  = method.GetGenericArguments()[0];
 | 
| 
 | 
   360 			var tbl    = new SqlTable(ttype);
 | 
| 
 | 
   361 
 | 
| 
 | 
   362 			var database     = tbl.Database     == null ? null : sp.Convert(tbl.Database,     ConvertType.NameToDatabase).  ToString();
 | 
| 
 | 
   363 			var owner        = tbl.Owner        == null ? null : sp.Convert(tbl.Owner,        ConvertType.NameToOwner).     ToString();
 | 
| 
 | 
   364 			var physicalName = tbl.PhysicalName == null ? null : sp.Convert(tbl.PhysicalName, ConvertType.NameToQueryTable).ToString();
 | 
| 
 | 
   365 
 | 
| 
 | 
   366 			var name   = sp.BuildTableName(new StringBuilder(), database, owner, physicalName);
 | 
| 
 | 
   367 
 | 
| 
 | 
   368 			arr.Add(new SqlExpression(name.ToString(), Precedence.Primary));
 | 
| 
 | 
   369 		}
 | 
| 
 | 
   370 
 | 
| 
 | 
   371 		{
 | 
| 
 | 
   372 			var field = ((ConstantExpression)expArgs.First()).Value;
 | 
| 
 | 
   373 
 | 
| 
 | 
   374 			if (field is string)
 | 
| 
 | 
   375 			{
 | 
| 
 | 
   376 				arr[0] = new SqlExpression(field.ToString(), Precedence.Primary);
 | 
| 
 | 
   377 			}
 | 
| 
 | 
   378 			else if (field is LambdaExpression)
 | 
| 
 | 
   379 			{
 | 
| 
 | 
   380 				var body = ((LambdaExpression)field).Body;
 | 
| 
 | 
   381 
 | 
| 
 | 
   382 				if (body is MemberExpression)
 | 
| 
 | 
   383 				{
 | 
| 
 | 
   384 					var name = ((MemberExpression)body).Member.Name;
 | 
| 
 | 
   385 
 | 
| 
 | 
   386 					name = sp.Convert(name, ConvertType.NameToQueryField).ToString();
 | 
| 
 | 
   387 
 | 
| 
 | 
   388 					arr[0] = new SqlExpression(name, Precedence.Primary);
 | 
| 
 | 
   389 				}
 | 
| 
 | 
   390 			}
 | 
| 
 | 
   391 		}
 | 
| 
 | 
   392 
 | 
| 
 | 
   393 		table.SqlTableType   = SqlTableType.Expression;
 | 
| 
 | 
   394 		table.Name           = ""FREETEXTTABLE({6}, {2}, {3}) {1}"";
 | 
| 
 | 
   395 		table.TableArguments = arr.ToArray();
 | 
| 
 | 
   396 	}
 | 
| 
 | 
   397 }
 | 
| 
 | 
   398 
 | 
| 
 | 
   399 [FreeTextTableExpressionAttribute]
 | 
| 
 | 
   400 public Table<FreeTextKey<TKey>> FreeTextTable<TTable,TKey>(string field, string text)
 | 
| 
 | 
   401 {
 | 
| 
 | 
   402 	return this.GetTable<FreeTextKey<TKey>>(
 | 
| 
 | 
   403 		this,
 | 
| 
 | 
   404 		((MethodInfo)(MethodBase.GetCurrentMethod())).MakeGenericMethod(typeof(TTable), typeof(TKey)),
 | 
| 
 | 
   405 		field,
 | 
| 
 | 
   406 		text);
 | 
| 
 | 
   407 }
 | 
| 
 | 
   408 
 | 
| 
 | 
   409 [FreeTextTableExpressionAttribute]
 | 
| 
 | 
   410 public Table<FreeTextKey<TKey>> FreeTextTable<TTable,TKey>(Expression<Func<TTable,string>> fieldSelector, string text)
 | 
| 
 | 
   411 {
 | 
| 
 | 
   412 	return this.GetTable<FreeTextKey<TKey>>(
 | 
| 
 | 
   413 		this,
 | 
| 
 | 
   414 		((MethodInfo)(MethodBase.GetCurrentMethod())).MakeGenericMethod(typeof(TTable), typeof(TKey)),
 | 
| 
 | 
   415 		fieldSelector,
 | 
| 
 | 
   416 		text);
 | 
| 
 | 
   417 }
 | 
| 
 | 
   418 
 | 
| 
 | 
   419 #endregion");
 | 
| 
 | 
   420 
 | 
| 
 | 
   421 		};
 | 
| 
 | 
   422 	}
 | 
| 
 | 
   423 }
 | 
| 
 | 
   424 #> |