コード例 #1
0
ファイル: DataMember.cs プロジェクト: okhosting/OKHOSTING.ORM
		/// <summary>
		/// Initializes a new instance of the <see cref="OKHOSTING.ORM.DataMember"/> class.
		/// <para xml:lang="es">
		/// Inicializa una nueva instancia de la clase OKHOSTING.ORM.DataMember
		/// </para>
		/// </summary>
		/// <param name="type">Type.
		/// <para xml:lang="es">El tipo del dato.</para>
		/// </param>
		/// <param name="member">Member.
		/// <para xml:lang="es">El miembro.</para>
		/// </param>
		/// <param name="column">Column.
		/// <para xml:lang="es">La columna.</para>
		/// </param>
		public DataMember(DataType type, string member, Column column)
		{
			if (type == null)
			{
				throw new ArgumentNullException("type");
			}

			if (string.IsNullOrWhiteSpace(member))
			{
				throw new ArgumentNullException("member");
			}

			DataType = type;
			Expression = new MemberExpression(type.InnerType, member);

			if (column == null)
			{
				CreateColumn();
			}
			else
			{
				if (column.Table != type.Table)
				{
					throw new ArgumentOutOfRangeException("column", column, "This column does not belong the the Table that TypeMap is mapped to");
				}

				Column = column;
			}
		}
コード例 #2
0
		public ColumnValue(Column column, object value)
		{
			if (column == null)
			{
				throw new ArgumentNullException("column");
			}

			Column = column;
			Value = value;
		}
コード例 #3
0
		/// <summary>
		/// Constructs the AggegateSelectField
		/// </summary>
		/// <param name="dataValue">
		/// DataMember for build the field definition
		/// </param>
		/// <param name="alias">
		/// Alias name of the resulting field
		/// </param>
		public SelectColumn(Column column, string alias)
		{
			if (column == null)
			{
				throw new ArgumentNullException("column");
			}

			Column = column;
			Alias = alias;
		}
コード例 #4
0
		/// <summary>
		/// Returns the full schema of the database including tables, indexes, foreign keys, etc.
		/// </summary>
		/// <remarks>
		/// It's very slow for large databases
		/// </remarks>
		public static DataBaseSchema Load(DataBase database, string schemaProvider)
		{
			DataBaseSchema schema = new DataBaseSchema();
			DatabaseSchema schemaReader;

			using (var dbReader = new DatabaseSchemaReader.DatabaseReader(database.ConnectionString, schemaProvider))
			{
				dbReader.AllTables();
				dbReader.AllViews();

				try
				{
					dbReader.AllStoredProcedures();
				}
				catch { }

				try
				{
					dbReader.AllUsers();
				}
				catch { }

				schemaReader = dbReader.DatabaseSchema;
			}

			foreach (DatabaseTable dbt in schemaReader.Tables)
			{
				if (dbt.PrimaryKeyColumn == null)
				{
					continue;
				}

				dbt.PrimaryKeyColumn.AddIdentity();

				var table = new Table()
				{
					Name = dbt.Name,
					DataBase = schema,
					IdentityIncrement = dbt.PrimaryKeyColumn.IdentityDefinition.IdentityIncrement,
					IdentitySeed = dbt.PrimaryKeyColumn.IdentityDefinition.IdentitySeed,
				};

				schema.Tables.Add(table);
			}

			foreach (DatabaseTable dbt in schemaReader.Tables)
			{
				if (dbt.PrimaryKeyColumn == null)
				{
					continue;
				}

				var table = schema[dbt.Name];

				foreach (DatabaseColumn dbc in dbt.Columns)
				{
					Column column = new Column()
					{
						Name = dbc.Name,
						Table = table,
						Description = dbc.Description,
						IsNullable = dbc.Nullable,
						IsAutoNumber = dbc.IsAutoNumber,
						ComputedDefinition = dbc.ComputedDefinition,
						DefaultValue = dbc.DefaultValue,
						IsPrimaryKey = dbc.IsPrimaryKey,
						Length = (uint?) dbc.Length,
						Ordinal = dbc.Ordinal,
						Precision = dbc.Precision,
						Scale = dbc.Scale,
					};

						
					if (dbc.DataType != null)
					{
						column.DbType = DbTypeMapper.Parse(dbc.DataType.GetNetType());
					}
					else
					{
						if(dbc.DbDataType.StartsWith("varchar"))
						{
							column.DbType = DbType.AnsiString;
						}
						else if (dbc.DbDataType.StartsWith("int"))
						{
							column.DbType = DbType.Int32;
						}
						else if (dbc.DbDataType.StartsWith("decimal"))
						{
							column.DbType = DbType.Decimal;
						}
						else if (dbc.DbDataType.StartsWith("datetime"))
						{
							column.DbType = DbType.DateTime;
						}
						else if (dbc.DbDataType.StartsWith("money"))
						{
							column.DbType = DbType.Currency;
						}
						else if (dbc.DbDataType.StartsWith("char"))
						{
							column.DbType = DbType.AnsiStringFixedLength;
						}
						else if (dbc.DbDataType.StartsWith("text"))
						{
							column.DbType = DbType.AnsiString;
						}
					}

					table.Columns.Add(column);
				}

				foreach (DatabaseIndex dbi in dbt.Indexes)
				{
					Index index = new Index()
					{
						Name = dbi.Name,
						Table = table,
						Direction = SortDirection.Ascending,
						Unique = dbi.IsUnique,
					};
					
					foreach (DatabaseColumn dbc in dbi.Columns)
					{
						index.Columns.Add(table[dbc.Name]);
					}
					
					table.Indexes.Add(index);
				}

				foreach (DatabaseTrigger dbtr in dbt.Triggers)
				{
					DataBaseOperation operation = DataBaseOperation.Insert;
					Enum.TryParse<DataBaseOperation>(dbtr.TriggerEvent, true, out operation);

					Trigger trigger = new Trigger()
					{
						TriggerBody = dbtr.TriggerBody,
						TriggerEvent = operation,
						Table = table,
					};

					table.Triggers.Add(trigger);
				}

				foreach (DatabaseConstraint dbcons in dbt.CheckConstraints)
				{
					if (dbcons.ConstraintType == ConstraintType.Check)
					{
						CheckConstraint constraint = new CheckConstraint()
						{
							Expression = dbcons.Expression,
							Table = table,
						};
						
						table.CheckConstraints.Add(constraint);
					}
					else if (dbcons.ConstraintType == ConstraintType.ForeignKey)
					{
						ForeignKey foreignKey = new ForeignKey()
						{
							Name= dbcons.Name,
							DeleteAction = schema.ParseConstraintAction(dbcons.DeleteRule),
							UpdateAction =schema.ParseConstraintAction(dbcons.UpdateRule),
							RemoteTable = schema[dbcons.RefersToTable],
							Table = table,
						};

						var referencedColumns = dbcons.ReferencedColumns(schemaReader).ToArray();
						for (int i = 0; i < dbcons.Columns.Count; i++)
						{
							foreignKey.Columns.Add(new Tuple<Column,Column>(table[dbcons.Columns[i]], foreignKey.RemoteTable[referencedColumns[i]]));
						}

						table.ForeignKeys.Add(foreignKey);
					}
				}
			}

			foreach (DatabaseView dbv in schemaReader.Views)
			{
				View view = new View()
				{
					Name = dbv.Name,
					Command = dbv.Sql,
					Description = dbv.Description,
					DataBase = schema,
				};

				schema.Views.Add(view);
			}

			foreach (DatabaseUser dbu in schemaReader.Users)
			{
				User user = new User()
				{
					Name = dbu.Name,
					DataBase = schema,
				};

				schema.Users.Add(user);
			}

			return schema;
		}
コード例 #5
0
		/// <summary>
		/// Creates a list of new DataTypes, creating as well a list of new Tables with all members of type as columns
		/// </summary>
		public static IEnumerable<DataType> DefaultMap(IEnumerable<Type> types)
		{
			//we will store here all types that are actually persistent
			List<DataType> persistentTypes = new List<DataType>();
			Random random = new Random();

			//map primary keys first, so we allow to foreign keys and inheritance to be correctly mapped
			foreach (Type type in types)
			{
				//skip enums and interfaces
				if (type.GetTypeInfo().IsEnum || type.GetTypeInfo().IsInterface)
				{
					continue;
				}

				//ignore types with no primary key
				var pk = GetMappableMembers(type).Where(m => DataMember.IsPrimaryKey(m));

				if (pk.Count() == 0)
				{
					continue;
				}

				DataType dtype = new DataType(type);
				AllDataTypes.Add(dtype);

				foreach (var memberInfo in pk)
				{
					//create datamember
					dtype.AddMember(memberInfo.Name);
				}

				persistentTypes.Add(dtype);
			}

			foreach (DataType dtype in persistentTypes)
			{
				//create inheritance foreign keys
				if (dtype.BaseDataType != null)
				{
					ForeignKey foreignKey = new ForeignKey();
					foreignKey.Table = dtype.Table;
					foreignKey.RemoteTable = dtype.BaseDataType.Table;
					foreignKey.Name = "FK_" + dtype.Name + "_" + dtype.BaseDataType.Name + "_" + random.Next();

					//we asume that primary keys on parent and child tables have the same number and order of related columns
					for (int i = 0; i < dtype.PrimaryKey.Count(); i++)
					{
						DataMember pk = dtype.PrimaryKey.ToArray()[i];
						DataMember basePk = dtype.BaseDataType.PrimaryKey.ToArray()[i];

						foreignKey.Columns.Add(new Tuple<Column, Column>(pk.Column, basePk.Column));
					}

					dtype.Table.ForeignKeys.Add(foreignKey);
				}

				//map non primary key members now
				foreach (var memberInfo in GetMappableMembers(dtype.InnerType).Where(m => !DataMember.IsPrimaryKey(m)))
				{
					Type returnType = MemberExpression.GetReturnType(memberInfo);

					//is this a collection of a mapped type? if so, ignore since this must be a 1-1, 1-many or many-many relationship and must be mapped somewhere else
					if (DataType.IsCollection(returnType) && IsMapped(returnType.GetCollectionItemType()))
					{
						continue;
					}

					//its a persistent type, with it's own table, map as a foreign key with one or more columns for the primary key
					if (IsMapped(returnType))
					{
						//we asume this datatype is already mapped along with it's primery key
						DataType returnDataType = returnType;

						ForeignKey foreignKey = new ForeignKey();
						foreignKey.Table = dtype.Table;
						foreignKey.RemoteTable = returnDataType.Table;
						foreignKey.Name = "FK_" + dtype.Name + "_" + memberInfo.Name + "_" + random.Next();

						foreach (DataMember pk in returnDataType.PrimaryKey.ToList())
						{
							Column column = new Column();
							column.Name = memberInfo.Name + "_" + pk.Member.Expression.Replace('.', '_');
							column.Table = dtype.Table;
							column.IsPrimaryKey = false;
							column.IsNullable = !RequiredValidator.IsRequired(memberInfo);
							column.DbType = DbTypeMapper.Parse(pk.Member.ReturnType);

							if (column.IsString)
							{
								column.Length = StringLengthValidator.GetMaxLength(pk.Member.FinalMemberInfo);
							}

							dtype.Table.Columns.Add(column);
							foreignKey.Columns.Add(new Tuple<Column, Column>(column, pk.Column));

							//create datamember
							dtype.AddMember(memberInfo.Name + "." + pk.Member, column);
						}

						dtype.Table.ForeignKeys.Add(foreignKey);
					}
					//just map as a atomic value
					else
					{
						Column column = new Column();
						column.Name = memberInfo.Name;
						column.Table = dtype.Table;
						column.IsNullable = !RequiredValidator.IsRequired(memberInfo);
						column.IsPrimaryKey = false;

						//create datamember
						DataMember dmember = dtype.AddMember(memberInfo.Name, column);

						//is this a regular atomic value?
						if (DbTypeMapper.DbTypeMap.ContainsValue(returnType) && returnType != typeof(object))
						{
							column.DbType = DbTypeMapper.Parse(returnType);
						}
						else if (returnType.GetTypeInfo().IsEnum)
						{
							column.DbType = DbType.Int32;
						}
						//this is an non-atomic object, but its not mapped as a DataType, so we serialize it as json
						else
						{
							column.DbType = DbType.String;
							dmember.Converter = new Conversions.Json<object>();
						}

						if (column.IsString)
						{
							column.Length = Data.Validation.StringLengthValidator.GetMaxLength(memberInfo);
						}

						dtype.Table.Columns.Add(column);
					}
				}

				yield return dtype;
			}
		}
コード例 #6
0
		public DataMember AddMember(string member, Column column)
		{
			var genericDataMemberType = typeof(DataMember<>).MakeGenericType(InnerType);

			ConstructorInfo constructor = genericDataMemberType.GetTypeInfo().DeclaredConstructors.Where(c => c.GetParameters().Length == 0).Single();
			DataMember genericDataMember = (DataMember) constructor.Invoke(null);
			genericDataMember.Member = new MemberExpression(InnerType, member);

			if (column == null)
			{
				genericDataMember.CreateColumn();
			}
			else
			{
				genericDataMember.Column = column;
			}

			DataMembers.Add(genericDataMember);

			return genericDataMember;
		}
コード例 #7
0
		/// <summary>
		/// Creates a new instance
		/// </summary>
		protected OrderBy(Column orderBy, SortDirection direction)
		{
			this.Column = orderBy;
			this.Direction = direction;
		}
コード例 #8
0
		/// <summary>
		/// Constructs the AggegateSelectField
		/// </summary>
		/// <param name="dataValue">
		/// DataMember for build the field definition
		/// </param>
		public SelectColumn(Column column): this(column, null)
		{ 
		}
コード例 #9
0
ファイル: DataMember.cs プロジェクト: okhosting/OKHOSTING.ORM
		/// <summary>
		/// Creates the column and the agregate to the table.
		/// <para xml:lang="es">
		/// Crea la columna y la agrega a la tabla.
		/// </para>
		/// </summary>
		public void CreateColumn()
		{
			var finalMember = Expression.FinalMemberInfo;
			var returnType = MemberExpression.GetReturnType(finalMember);

			Column = new Column()
			{
				Table = DataType.Table,
				Name = Expression.Expression.Replace('.', '_'),
				IsPrimaryKey = IsPrimaryKey(Expression),
				IsNullable = !RequiredValidator.IsRequired(finalMember) && !IsPrimaryKey(Expression),
			};

			//is this a regular atomic value?
			if (Sql.DbTypeMapper.DbTypeMap.ContainsValue(returnType) && returnType != typeof(object))
			{
				Column.DbType = Sql.DbTypeMapper.Parse(returnType);
			}
			else if (returnType.GetTypeInfo().IsEnum)
			{
				Column.DbType = Sql.DbType.Int32;
			}
			//this is an non-atomic object, but its not mapped as a DataType, so we serialize it as json
			else
			{
				Column.DbType = Sql.DbType.String;
				Converter = new Conversions.JsonConverter<object>();
			}

			if (Column.IsString)
			{
				Column.Length = StringLengthValidator.GetMaxLength(finalMember);
			}

			if (MemberExpression.GetReturnType(finalMember) == typeof(Guid))
			{
				Column.Length = 38;
			}

			Column.IsAutoNumber = Column.IsNumeric && Column.IsPrimaryKey && DataType.BaseDataType == null;

			DataType.Table.Columns.Add(Column);
		}
コード例 #10
0
		/// <summary>
		/// Returns the name of the specified field completly qualified
		/// </summary>
		/// <param name="column">
		/// Column to format
		/// </param>
		/// <returns>
		/// Name of the specified field completly qualified
		/// </returns>
		protected virtual string ColumnFullName(Column column)
		{
			return EncloseName(column.Table.Name) + "." + EncloseName(column.Name);
		}
コード例 #11
0
		/// <summary>
		/// Constructs the AggegateSelectField
		/// </summary>
		/// <param name="dataValue">
		/// DataMember for build the field definition
		/// </param>
		/// <param name="aggregateFunction">
		/// Aggregate function to use for calculate the column
		/// </param>
		/// <param name="distinct">
		/// Speficy if the DISTINCT modifier must be applied
		/// </param>
		/// <param name="alias">
		/// Alias name of the resulting field
		/// </param>
		public SelectAggregateColumn(Column column, SelectAggregateFunction aggregateFunction, string alias, bool distinct): base(column, alias)
		{
			AggregateFunction = aggregateFunction;
			Distinct = distinct;
		}
コード例 #12
0
		/// <summary>
		/// Constructs the AggegateSelectField
		/// </summary>
		/// <param name="dataValue">
		/// DataMember for build the field definition
		/// </param>
		/// <param name="aggregateFunction">
		/// Aggregate function to use for calculate the column
		/// </param>
		/// <param name="alias">
		/// Alias name of the resulting field
		/// </param>
		public SelectAggregateColumn(Column column, SelectAggregateFunction aggregateFunction, string alias) : this(column, aggregateFunction, alias, false) { }
コード例 #13
0
		/// <summary>
		/// Constructs the AggegateSelectField
		/// </summary>
		/// <param name="dataValue">
		/// DataMember for build the field definition
		/// </param>
		/// <param name="aggregateFunction">
		/// Aggregate function to use for calculate the column
		/// </param>
		public SelectAggregateColumn(Column column, SelectAggregateFunction aggregateFunction) : this(column, aggregateFunction, string.Empty) { }
コード例 #14
0
		/// <summary>
		/// Constructs the AggegateSelectField
		/// </summary>
		/// <param name="dataValue">
		/// DataMember for build the field definition
		/// </param>
		public SelectAggregateColumn(Column column): this(column, SelectAggregateFunction.None) 
		{ 
		}
コード例 #15
0
		public void CreateColumn()
		{
			var finalMember = Member.FinalMemberInfo;

			Column = new Column()
			{
				Table = DataType.Table,
				Name = Member.Expression.Replace('.', '_'),
				DbType = Sql.DbTypeMapper.Parse(MemberExpression.GetReturnType(finalMember)),
				IsNullable = !RequiredValidator.IsRequired(finalMember),
				IsPrimaryKey = IsPrimaryKey(finalMember),
			};

			Column.IsAutoNumber = Column.IsNumeric && Column.IsPrimaryKey && DataType.BaseDataType == null;

			if (Column.IsString)
			{
				Column.Length = StringLengthValidator.GetMaxLength(finalMember);
			}

			DataType.Table.Columns.Add(Column);
		}
コード例 #16
0
ファイル: DataType.cs プロジェクト: okhosting/OKHOSTING.ORM
		/// <summary>
		/// Add the member who brings as a parameter and creates a column for this member.
		/// <para xml:lang="es">
		/// Agrega el miembro que trae como parametro y crea una columna para este miembro.
		/// </para>
		/// </summary>
		/// <returns>The member.</returns>
		/// <param name="member">Member.
		/// <para xml:lang="es">El Miembro.</para>
		/// </param>
		/// <param name="column">Column.
		/// <para xml:lang="es">La Columna.</para>
		/// </param>
		public DataMember AddMember(string member, Column column)
		{
			if (string.IsNullOrWhiteSpace(member))
			{
				throw new ArgumentNullException(nameof(member));
			}

			if (AllDataMembers.Where(dm => dm.Expression.Expression == member).Any())
			{
				throw new ArgumentOutOfRangeException(string.Format("Member {0} is already mapped in DataType {1}", member, FullName));
			}

			var genericDataMemberType = typeof(DataMember<>).MakeGenericType(InnerType);

			ConstructorInfo constructor = genericDataMemberType.GetTypeInfo().DeclaredConstructors.Where(c => c.GetParameters().Length == 0).Single();
			DataMember genericDataMember = (DataMember) constructor.Invoke(null);
			genericDataMember.Expression = new MemberExpression(InnerType, member);

			//If there is no column for this member, create one.
			if (column == null)
			{
				genericDataMember.CreateColumn();
			}
			//otherwise, it assigns the column that receives as a parameter
			else
			{
				genericDataMember.Column = column;
			}

			((List<DataMember>) DataMembers).Add(genericDataMember);

			return genericDataMember;
		}
コード例 #17
0
		/// <summary>
		/// Returns the DML for create the column corresponding 
		/// with the specified Column
		/// </summary>
		/// <param name="column">
		/// Column for DML column creation
		/// </param>
		/// <returns>
		/// DML for create the column corresponding 
		/// with the specified Column
		/// </returns>
		protected virtual Command CreateColumnClause(Column column)
		{
			//Append the column Name
			string columnDefinition = EncloseName(column.Name) + " ";

			//if this is a string value, format as a string
			if (column.IsString)
			{
				if (column.Length.HasValue && column.Length > 0)
				{
					columnDefinition += FormatStringType(column.Length.Value);
				}
				else
				{
					//unlimited lenght by default
					columnDefinition += FormatStringType(0);
				}
			}
			//otherwise, format normally
			else
			{
				columnDefinition += Format(column.DbType);
			}

			if (!column.IsNullable)
			{
				columnDefinition += " NOT " + Null;
			}
			else
			{
				columnDefinition += " " + Null;
			}

			//Append the AutoIncrement flag, only if column is not part of a foreign key
			if (column.IsAutoNumber)
			{
				columnDefinition += " " + AutoIncrementalSettingName;
			}

			//Returning the column definition 
			return columnDefinition;
		}
コード例 #18
0
		/// <summary>
		/// Creates a new instance
		/// </summary>
		protected OrderBy(Column orderBy): this(orderBy, SortDirection.Ascending)
		{
		}
コード例 #19
0
		/// <summary>
		/// Returns the DML for create the column corresponding 
		/// with the specified DataMember
		/// </summary>
		/// <param name="dataValue">
		/// DataMember for DML column creation
		/// </param>
		/// <returns>
		/// DML for create the column corresponding 
		/// with the specified DataMember
		/// </returns>
		protected override Command CreateColumnClause(Column column)
		{
			//if this is not an autoincrement column, use the base method
			if (!column.IsAutoNumber)
			{
				return base.CreateColumnClause(column);
			}

			//Append the column Name 
			string columnDefinition = EncloseName(column.Name) + " ";

			//use Autoincrement as the TypeMap<T>
			columnDefinition += " " + AutoIncrementalSettingName;

			//Append the NULL flag
			if (!column.IsNullable) columnDefinition += " NOT " + Null;
			else columnDefinition += " " + Null;

			//Returning the column definition 
			return columnDefinition;
		}