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); }
/// <summary> /// Creates a field for a DataMember /// </summary> public FormField AddField(MemberInfo member) { //if there's no values defined, exit if (member == null) { throw new ArgumentNullException(nameof(member)); } //field FormField field; Type returnType = MemberExpression.GetReturnType(member); //String if (returnType.Equals(typeof(string))) { field = new StringField(); //set max lenght, if defined int maxLenght = (int)StringLengthValidator.GetMaxLength(member); if (maxLenght == 0) { field.TableWide = true; } else { ((StringField)field).MaxLenght = maxLenght; } //set regular expression validation, if defined var regex = member.CustomAttributes.Where(att => att.AttributeType.Equals(typeof(RegexValidator))).SingleOrDefault(); if (regex != null) { ((StringField)field).RegularExpression = (string)regex.ConstructorArguments[0].Value; } } //DataType else if (returnType.Equals(typeof(DataType))) { field = new DataTypeField(); } //otherwise delegate to the static method to create the field from the return type else { field = CreateField(returnType); } field.Name = member.Name; field.Container = this; field.Required = RequiredValidator.IsRequired(member); field.CaptionControl.Text = Translator.Translate(member); //if (member.Column.IsPrimaryKey) field.SortOrder = 0; //add to fields collection Fields.Add(field); return(field); }
/// <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); } }