/// <summary> /// Dispatches the call to the extensions. /// </summary> /// <param name="pi">The property info reflection object.</param> /// <param name="hasAndBelongManyModel">The has and belong many model.</param> /// <param name="model">The model.</param> public void ProcessHasAndBelongsToMany(PropertyInfo pi, HasAndBelongsToManyModel hasAndBelongManyModel, ActiveRecordModel model) { foreach (IModelBuilderExtension extension in extensions) { extension.ProcessHasAndBelongsToMany(pi, hasAndBelongManyModel, model); } }
public override void VisitHasAndBelongsToMany(HasAndBelongsToManyModel model) { HasAndBelongsToManyAttribute att = model.HasManyAtt; WriteCollection(att.Cascade, att.MapType, att.RelationType, model.Property.Name, att.AccessString, att.Table, att.Schema, att.Lazy, att.Inverse, att.OrderBy, att.Where, att.Sort, att.ColumnKey, att.ColumnRef, model.CollectionID, att.Index, att.IndexType, att.Cache); }
public override void VisitHasAndBelongsToMany(HasAndBelongsToManyModel model) { model.HasManyAtt.RelationType = GuessRelation(model.Property, model.HasManyAtt.RelationType); Type otherend = model.HasManyAtt.MapType; if (model.HasManyAtt.Table == null) { throw new ActiveRecordException(String.Format( "For a many to many association (HasAndBelongsToMany) we need that you " + "specify the association table - {0}.{1} " + currentModel.Type.Name, model.Property.Name)); } if (model.HasManyAtt.ColumnKey == null) { throw new ActiveRecordException(String.Format( "For a many to many association (HasAndBelongsToMany) we need that you " + "specify the ColumnKey - which is the column that represents the type {0} " + "on the association table - {0}.{1} " + currentModel.Type.Name, model.Property.Name)); } if (model.HasManyAtt.ColumnRef == null) { throw new ActiveRecordException(String.Format( "For a many to many association (HasAndBelongsToMany) we need that you " + "specify the ColumnRef - which is the column that represents the other end '{2}' " + "on the association table - {0}.{1} " + currentModel.Type.Name, model.Property.Name, otherend.Name)); } if (model.HasManyAtt.RelationType == RelationType.IdBag && model.CollectionID == null) { throw new ActiveRecordException(String.Format( "For a many to many association (HasAndBelongsToMany) using IDBag, you need " + "to specify a CollectionIDAttribute giving us more details. " + "{0}.{1} " + currentModel.Type.Name, model.Property.Name, otherend.Name)); } if (model.HasManyAtt.RelationType == RelationType.Map && model.HasManyAtt.Index == null) { throw new ActiveRecordException(String.Format( "A HasAndBelongsToMany with type Map requires that you specify an 'Index', use the Index property {0}.{1} ", model.Property.DeclaringType.Name, model.Property.Name)); } base.VisitHasAndBelongsToMany(model); }
public override void VisitCollectionID(CollectionIDModel model) { // Attempt to find HasAndBelongsToMany for the property HasAndBelongsToManyModel hasAndBelModel = FindHasAndBelongsToMany(model.Property); if (hasAndBelModel == null) { throw new ActiveRecordException(String.Format( "A CollectionIDAttribute should be used with HasAndBelongsToMany, but we couldn't find it for the property " + currentModel.Type.FullName + "." + model.Property.Name)); } hasAndBelModel.CollectionID = model; }
/// <summary> /// Dispatches the call to the extensions. /// </summary> /// <param name="pi">The property info reflection object.</param> /// <param name="hasAndBelongManyModel">The has and belong many model.</param> /// <param name="model">The model.</param> public void ProcessHasAndBelongsToMany(PropertyInfo pi, HasAndBelongsToManyModel hasAndBelongManyModel, ActiveRecordModel model) { foreach(IModelBuilderExtension extension in extensions) { extension.ProcessHasAndBelongsToMany(pi, hasAndBelongManyModel, model); } }
private void ProcessProperties(Type type, ActiveRecordModel model) { // Check persistent properties of the base class as well if (ShouldCheckBase(type)) { ProcessProperties(type.BaseType, model); } PropertyInfo[] props = type.GetProperties(DefaultBindingFlags); foreach(PropertyInfo prop in props) { bool isArProperty = false; AnyModel anyModel; HasManyToAnyModel hasManyToAnyModel; if (extension != null) { extension.ProcessProperty(prop, model); } object[] valAtts = prop.GetCustomAttributes(typeof(AbstractValidationAttribute), true); foreach(AbstractValidationAttribute valAtt in valAtts) { IValidator validator = valAtt.Build(); validator.Initialize(validatorRegistry, prop); model.Validators.Add(validator); } foreach(object attribute in prop.GetCustomAttributes(false)) { if (attribute is PrimaryKeyAttribute) { PrimaryKeyAttribute propAtt = attribute as PrimaryKeyAttribute; isArProperty = true; // Joined Subclasses must not have PrimaryKey if (type.IsDefined(typeof(JoinedBaseAttribute), true) && // JoinedBase in a superclass !type.IsDefined(typeof(JoinedBaseAttribute), false)) // but not here { throw new ActiveRecordException("You can't specify a PrimaryKeyAttribute in a joined subclass. " + "Check type " + model.Type.FullName); } if (prop.PropertyType.IsDefined(typeof(CompositeKeyAttribute), true)) { object[] att = prop.PropertyType.GetCustomAttributes(typeof(CompositeKeyAttribute), true); CompositeKeyAttribute cAtt = att[0] as CompositeKeyAttribute; model.CompositeKey = new CompositeKeyModel(prop, cAtt); } else { if (!propAtt.IsOverride && model.PrimaryKey != null) { throw new ActiveRecordException("You can't specify more than one PrimaryKeyAttribute in a " + "class. Check type " + model.Type.FullName); } model.PrimaryKey = new PrimaryKeyModel(prop, propAtt); } } else if (attribute is CompositeKeyAttribute) { CompositeKeyAttribute propAtt = attribute as CompositeKeyAttribute; isArProperty = true; model.CompositeKey = new CompositeKeyModel(prop, propAtt); } else if (attribute is AnyAttribute) { AnyAttribute anyAtt = attribute as AnyAttribute; isArProperty = true; anyModel = new AnyModel(prop, anyAtt); model.Anys.Add(anyModel); CollectMetaValues(anyModel.MetaValues, prop); } else if (attribute is PropertyAttribute) { PropertyAttribute propAtt = attribute as PropertyAttribute; isArProperty = true; // If this property overrides a base class property remove the old one if (propAtt.IsOverride) { for (int index = 0; index < model.Properties.Count; ++index) { PropertyModel oldModel = (PropertyModel)model.Properties[index]; if (oldModel.Property.Name == prop.Name) { model.Properties.RemoveAt(index); break; } } } PropertyModel propModel = new PropertyModel(prop, propAtt); model.Properties.Add(propModel); model.PropertyDictionary[prop.Name] = propModel; } else if (attribute is NestedAttribute) { NestedAttribute propAtt = attribute as NestedAttribute; isArProperty = true; ActiveRecordModel nestedModel = new ActiveRecordModel(prop.PropertyType); nestedModel.IsNestedType = true; Type nestedType = propAtt.MapType ?? prop.PropertyType; nestedModel.IsNestedCompositeType = model.IsNestedCompositeType; ProcessProperties(nestedType, nestedModel); ProcessFields(nestedType, nestedModel); NestedModel nested = new NestedModel(prop, propAtt, nestedModel); nestedModel.ParentNested = nested; model.Components.Add(nested); } else if (attribute is NestedParentReferenceAttribute) { NestedParentReferenceAttribute nestedParentAtt = attribute as NestedParentReferenceAttribute; isArProperty = true; model.ComponentParent.Add(new NestedParentReferenceModel(prop, nestedParentAtt)); } else if (attribute is JoinedKeyAttribute) { JoinedKeyAttribute propAtt = attribute as JoinedKeyAttribute; isArProperty = true; if (model.Key != null) { throw new ActiveRecordException("You can't specify more than one JoinedKeyAttribute. " + "Check type " + model.Type.FullName); } model.Key = new KeyModel(prop, propAtt); } else if (attribute is VersionAttribute) { VersionAttribute propAtt = attribute as VersionAttribute; isArProperty = true; if (model.Version != null) { throw new ActiveRecordException("You can't specify more than one VersionAttribute. " + "Check type " + model.Type.FullName); } model.Version = new VersionModel(prop, propAtt); } else if (attribute is TimestampAttribute) { TimestampAttribute propAtt = attribute as TimestampAttribute; isArProperty = true; if (model.Timestamp != null) { throw new ActiveRecordException("You can't specify more than one TimestampAttribute. " + "Check type " + model.Type.FullName); } model.Timestamp = new TimestampModel(prop, propAtt); } // Relations else if (attribute is OneToOneAttribute) { OneToOneAttribute propAtt = attribute as OneToOneAttribute; isArProperty = true; model.OneToOnes.Add(new OneToOneModel(prop, propAtt)); } else if (attribute is BelongsToAttribute) { BelongsToAttribute propAtt = attribute as BelongsToAttribute; isArProperty = true; BelongsToModel btModel = new BelongsToModel(prop, propAtt); model.BelongsTo.Add(btModel); model.BelongsToDictionary[prop.Name] = btModel; if (extension != null) { extension.ProcessBelongsTo(prop, btModel, model); } } // The ordering is important here, HasManyToAny must comes before HasMany! else if (attribute is HasManyToAnyAttribute) { HasManyToAnyAttribute propAtt = attribute as HasManyToAnyAttribute; isArProperty = true; hasManyToAnyModel = new HasManyToAnyModel(prop, propAtt); model.HasManyToAny.Add(hasManyToAnyModel); model.HasManyToAnyDictionary[prop.Name] = hasManyToAnyModel; CollectMetaValues(hasManyToAnyModel.MetaValues, prop); if (extension != null) { extension.ProcessHasManyToAny(prop, hasManyToAnyModel, model); } } else if (attribute is HasManyAttribute) { HasManyAttribute propAtt = attribute as HasManyAttribute; isArProperty = true; HasManyModel hasManyModel = new HasManyModel(prop, propAtt); if (propAtt.DependentObjects) { ActiveRecordModel dependentObjectModel = new ActiveRecordModel(propAtt.MapType); dependentObjectModel.IsNestedType = true; dependentObjectModel.IsNestedCompositeType = true; ProcessProperties(propAtt.MapType, dependentObjectModel); hasManyModel.DependentObjectModel = new DependentObjectModel(prop, propAtt, dependentObjectModel); } model.HasMany.Add(hasManyModel); model.HasManyDictionary[prop.Name] = hasManyModel; if (extension != null) { extension.ProcessHasMany(prop, hasManyModel, model); } } else if (attribute is HasAndBelongsToManyAttribute) { HasAndBelongsToManyAttribute propAtt = attribute as HasAndBelongsToManyAttribute; isArProperty = true; HasAndBelongsToManyModel habtManyModel = new HasAndBelongsToManyModel(prop, propAtt); model.HasAndBelongsToMany.Add(habtManyModel); model.HasAndBelongsToManyDictionary[prop.Name] = habtManyModel; if (extension != null) { extension.ProcessHasAndBelongsToMany(prop, habtManyModel, model); } } else if (attribute is Any.MetaValueAttribute) { if (prop.GetCustomAttributes(typeof(HasManyToAnyAttribute), false).Length == 0 && prop.GetCustomAttributes(typeof(AnyAttribute), false).Length == 0 ) throw new ActiveRecordException( "You can't specify an Any.MetaValue without specifying the Any or HasManyToAny attribute. " + "Check type " + prop.DeclaringType.FullName); } else if (attribute is CompositeUserTypeAttribute) { CompositeUserTypeAttribute propAtt = attribute as CompositeUserTypeAttribute; isArProperty = true; model.CompositeUserType.Add(new CompositeUserTypeModel(prop, propAtt)); } if (attribute is CollectionIDAttribute) { CollectionIDAttribute propAtt = attribute as CollectionIDAttribute; model.CollectionIDs.Add(new CollectionIDModel(prop, propAtt)); } if (attribute is HiloAttribute) { HiloAttribute propAtt = attribute as HiloAttribute; model.Hilos.Add(new HiloModel(prop, propAtt)); } } if (!isArProperty) { model.NotMappedProperties.Add(prop); } } }
/// <summary> /// Visits the has and belongs to many. /// </summary> /// <remarks> /// Verify that a link table was specified /// Verify that a key was specified and that it is valid /// Verify that required information was specified /// </remarks> /// <param name="model">The model.</param> public override void VisitHasAndBelongsToMany(HasAndBelongsToManyModel model) { if (model.HasManyAtt.MapType == null) model.HasManyAtt.MapType = GuessType(null, model.Property.PropertyType); model.HasManyAtt.RelationType = GuessRelation(model.Property, model.HasManyAtt.RelationType); Type otherend = GuessType(model.HasManyAtt.MapType, model.Property.PropertyType); if (model.HasManyAtt.Table == null) { throw new ActiveRecordException(String.Format( "For a many to many association (HasAndBelongsToMany) we need that you " + "specify the association table - {0}.{1} ", currentModel.Type.Name, model.Property.Name)); } if (model.HasManyAtt.ColumnKey == null && model.HasManyAtt.CompositeKeyColumnKeys == null) { throw new ActiveRecordException(String.Format( "For a many to many association (HasAndBelongsToMany) we need that you " + "specify the ColumnKey or CompositeKeyColumnKeys - which is the column(s) that represents the type {0} " + "on the association table - {0}.{1} ", currentModel.Type.Name, model.Property.Name)); } if (model.HasManyAtt.ColumnKey != null && model.HasManyAtt.CompositeKeyColumnKeys != null) { throw new ActiveRecordException(String.Format( "For a many to many association (HasAndBelongsToMany) there should only be " + "a ColumnKey or an array of CompositeKeyColumnKeys, not both.")); } if (model.HasManyAtt.CompositeKeyColumnKeys != null && model.HasManyAtt.CompositeKeyColumnKeys.Length < 2) { throw new ActiveRecordException(String.Format( "For a many to many association (HasAndBelongsToMany) with a CompositeKey, " + "there must be at least two CompositeKeyColumnKeys - which are the columns that represent the type {0} " + "on the association table - {0}.{1} ", currentModel.Type.Name, model.Property.Name)); } if (model.HasManyAtt.RelationType != RelationType.IdBag && model.HasManyAtt.ColumnRef == null && model.HasManyAtt.CompositeKeyColumnRefs == null) { throw new ActiveRecordException(String.Format( "For a many to many association (HasAndBelongsToMany) we need that you " + "specify the ColumnRef or CompositeKeyColumnRefs - which is the column(s) that represents the other end '{2}' " + "on the association table - {0}.{1} ", currentModel.Type.Name, model.Property.Name, otherend.Name)); } if (model.HasManyAtt.ColumnRef != null && model.HasManyAtt.CompositeKeyColumnRefs != null) { throw new ActiveRecordException(String.Format( "For a many to many association (HasAndBelongsToMany) there should only be " + "a ColumnRef or an array of CompositeKeyColumnRefs, not both.")); } if (model.HasManyAtt.CompositeKeyColumnRefs != null && model.HasManyAtt.CompositeKeyColumnRefs.Length < 2) { throw new ActiveRecordException(String.Format( "For a many to many association (HasAndBelongsToMany) with a CompositeKey, " + "there must be at least two CompositeKeyColumnRefs - which are the columns that represent the other end '{2}' " + "on the association table - {0}.{1} ", currentModel.Type.Name, model.Property.Name, otherend.Name)); } if (model.HasManyAtt.RelationType == RelationType.IdBag && model.CollectionID == null) { throw new ActiveRecordException(String.Format( "For a many to many association (HasAndBelongsToMany) using IDBag, you need " + "to specify a CollectionIDAttribute giving us more details. " + "{0}.{1} ", currentModel.Type.Name, model.Property.Name)); } if (model.HasManyAtt.RelationType == RelationType.Map && model.HasManyAtt.Index == null) { throw new ActiveRecordException(String.Format( "A HasAndBelongsToMany with type Map requires that you specify an 'Index', use the Index property {0}.{1} ", model.Property.DeclaringType.Name, model.Property.Name)); } if (model.HasManyAtt.RelationType == RelationType.List && model.HasManyAtt.Index == null) { throw new ActiveRecordException(String.Format( "A HasAndBelongsToMany with type List requires that you specify an 'Index', use the Index property {0}.{1} ", model.Property.DeclaringType.Name, model.Property.Name)); } base.VisitHasAndBelongsToMany(model); }
/// <summary> /// Visits the has and belongs to many. /// </summary> /// <param name="model">The model.</param> public override void VisitHasAndBelongsToMany(HasAndBelongsToManyModel model) { HasAndBelongsToManyAttribute att = model.HasManyAtt; Type mapType = GuessType(att.MapType, model.Property.PropertyType); WriteCollection(att.Cascade, mapType, att.RelationType, model.Property.Name, att.AccessString, att.Table, att.Schema, att.Lazy, att.Inverse, att.OrderBy, att.Where, att.Sort, att.ColumnKey, att.CompositeKeyColumnKeys, att.Element, att.ElementType, att.ColumnRef, att.CompositeKeyColumnRefs, model.CollectionID, att.Index, att.IndexType, att.Cache, att.CacheRegion, att.NotFoundBehaviour, att.Fetch, att.BatchSize, att.CollectionType); }
private void ProcessProperties(Type type, ActiveRecordModel model) { // Check persistent properties of the base class as well if (ShouldCheckBase(type)) { ProcessProperties(type.BaseType, model); } PropertyInfo[] props = type.GetProperties(DefaultBindingFlags); foreach (PropertyInfo prop in props) { bool isArProperty = false; AnyModel anyModel; HasManyToAnyModel hasManyToAnyModel; if (extension != null) { extension.ProcessProperty(prop, model); } object[] valAtts = prop.GetCustomAttributes(typeof(AbstractValidationAttribute), true); foreach (AbstractValidationAttribute valAtt in valAtts) { IValidator validator = valAtt.Build(); validator.Initialize(validatorRegistry, prop); model.Validators.Add(validator); } foreach (object attribute in prop.GetCustomAttributes(false)) { if (attribute is PrimaryKeyAttribute) { PrimaryKeyAttribute propAtt = attribute as PrimaryKeyAttribute; isArProperty = true; // Joined Subclasses must not have PrimaryKey if (HasJoinedBase(type)) { throw new ActiveRecordException("You can't specify a PrimaryKeyAttribute in a joined subclass. " + "Check type " + model.Type.FullName); } if (prop.PropertyType.IsDefined(typeof(CompositeKeyAttribute), true)) { object[] att = prop.PropertyType.GetCustomAttributes(typeof(CompositeKeyAttribute), true); CompositeKeyAttribute cAtt = att[0] as CompositeKeyAttribute; model.CompositeKey = new CompositeKeyModel(prop, cAtt); } else { if (!propAtt.IsOverride && model.PrimaryKey != null) { throw new ActiveRecordException("You can't specify more than one PrimaryKeyAttribute in a " + "class. Check type " + model.Type.FullName); } model.PrimaryKey = new PrimaryKeyModel(prop, propAtt); } } else if (attribute is CompositeKeyAttribute) { CompositeKeyAttribute propAtt = attribute as CompositeKeyAttribute; isArProperty = true; model.CompositeKey = new CompositeKeyModel(prop, propAtt); } else if (attribute is AnyAttribute) { AnyAttribute anyAtt = attribute as AnyAttribute; isArProperty = true; anyModel = new AnyModel(prop, anyAtt); model.Anys.Add(anyModel); CollectMetaValues(anyModel.MetaValues, prop); } else if (attribute is PropertyAttribute) { PropertyAttribute propAtt = attribute as PropertyAttribute; isArProperty = true; // If this property overrides a base class property remove the old one if (propAtt.IsOverride) { for (int index = 0; index < model.Properties.Count; ++index) { PropertyModel oldModel = (PropertyModel)model.Properties[index]; if (oldModel.Property.Name == prop.Name) { model.Properties.RemoveAt(index); break; } } } PropertyModel propModel = new PropertyModel(prop, propAtt); model.Properties.Add(propModel); model.PropertyDictionary[prop.Name] = propModel; } else if (attribute is NestedAttribute) { NestedAttribute propAtt = attribute as NestedAttribute; isArProperty = true; ActiveRecordModel nestedModel = new ActiveRecordModel(prop.PropertyType); nestedModel.IsNestedType = true; Type nestedType = propAtt.MapType ?? prop.PropertyType; nestedModel.IsNestedCompositeType = model.IsNestedCompositeType; ProcessProperties(nestedType, nestedModel); ProcessFields(nestedType, nestedModel); NestedModel nested = new NestedModel(prop, propAtt, nestedModel); nestedModel.ParentNested = nested; model.Components.Add(nested); } else if (attribute is NestedParentReferenceAttribute) { NestedParentReferenceAttribute nestedParentAtt = attribute as NestedParentReferenceAttribute; isArProperty = true; model.ComponentParent.Add(new NestedParentReferenceModel(prop, nestedParentAtt)); } else if (attribute is JoinedKeyAttribute) { JoinedKeyAttribute propAtt = attribute as JoinedKeyAttribute; isArProperty = true; if (model.Key != null) { throw new ActiveRecordException("You can't specify more than one JoinedKeyAttribute. " + "Check type " + model.Type.FullName); } model.Key = new KeyModel(prop, propAtt); } else if (attribute is VersionAttribute) { VersionAttribute propAtt = attribute as VersionAttribute; isArProperty = true; if (model.Version != null) { throw new ActiveRecordException("You can't specify more than one VersionAttribute. " + "Check type " + model.Type.FullName); } model.Version = new VersionModel(prop, propAtt); } else if (attribute is TimestampAttribute) { TimestampAttribute propAtt = attribute as TimestampAttribute; isArProperty = true; if (model.Timestamp != null) { throw new ActiveRecordException("You can't specify more than one TimestampAttribute. " + "Check type " + model.Type.FullName); } model.Timestamp = new TimestampModel(prop, propAtt); } // Relations else if (attribute is OneToOneAttribute) { OneToOneAttribute propAtt = attribute as OneToOneAttribute; isArProperty = true; model.OneToOnes.Add(new OneToOneModel(prop, propAtt)); } else if (attribute is BelongsToAttribute) { BelongsToAttribute propAtt = attribute as BelongsToAttribute; isArProperty = true; BelongsToModel btModel = new BelongsToModel(prop, propAtt); model.BelongsTo.Add(btModel); model.BelongsToDictionary[prop.Name] = btModel; if (extension != null) { extension.ProcessBelongsTo(prop, btModel, model); } } // The ordering is important here, HasManyToAny must comes before HasMany! else if (attribute is HasManyToAnyAttribute) { HasManyToAnyAttribute propAtt = attribute as HasManyToAnyAttribute; isArProperty = true; hasManyToAnyModel = new HasManyToAnyModel(prop, propAtt); model.HasManyToAny.Add(hasManyToAnyModel); model.HasManyToAnyDictionary[prop.Name] = hasManyToAnyModel; CollectMetaValues(hasManyToAnyModel.MetaValues, prop); if (extension != null) { extension.ProcessHasManyToAny(prop, hasManyToAnyModel, model); } } else if (attribute is HasManyAttribute) { HasManyAttribute propAtt = attribute as HasManyAttribute; isArProperty = true; HasManyModel hasManyModel = new HasManyModel(prop, propAtt, model); if (propAtt.DependentObjects) { ActiveRecordModel dependentObjectModel = new ActiveRecordModel(propAtt.MapType); dependentObjectModel.IsNestedType = true; dependentObjectModel.IsNestedCompositeType = true; ProcessProperties(propAtt.MapType, dependentObjectModel); hasManyModel.DependentObjectModel = new DependentObjectModel(prop, propAtt, dependentObjectModel); } model.HasMany.Add(hasManyModel); model.HasManyDictionary[prop.Name] = hasManyModel; if (extension != null) { extension.ProcessHasMany(prop, hasManyModel, model); } } else if (attribute is HasAndBelongsToManyAttribute) { HasAndBelongsToManyAttribute propAtt = attribute as HasAndBelongsToManyAttribute; isArProperty = true; HasAndBelongsToManyModel habtManyModel = new HasAndBelongsToManyModel(prop, propAtt); model.HasAndBelongsToMany.Add(habtManyModel); model.HasAndBelongsToManyDictionary[prop.Name] = habtManyModel; if (extension != null) { extension.ProcessHasAndBelongsToMany(prop, habtManyModel, model); } } else if (attribute is Any.MetaValueAttribute) { if (prop.GetCustomAttributes(typeof(HasManyToAnyAttribute), false).Length == 0 && prop.GetCustomAttributes(typeof(AnyAttribute), false).Length == 0 ) { throw new ActiveRecordException( "You can't specify an Any.MetaValue without specifying the Any or HasManyToAny attribute. " + "Check type " + prop.DeclaringType.FullName); } } else if (attribute is CompositeUserTypeAttribute) { CompositeUserTypeAttribute propAtt = attribute as CompositeUserTypeAttribute; isArProperty = true; model.CompositeUserType.Add(new CompositeUserTypeModel(prop, prop.PropertyType, propAtt)); } if (attribute is CollectionIDAttribute) { CollectionIDAttribute propAtt = attribute as CollectionIDAttribute; model.CollectionIDs.Add(new CollectionIDModel(prop, propAtt)); } if (attribute is HiloAttribute) { HiloAttribute propAtt = attribute as HiloAttribute; model.Hilos.Add(new HiloModel(prop, propAtt)); } } if (!isArProperty) { model.NotMappedProperties.Add(prop); } } }
public virtual void VisitHasAndBelongsToMany(HasAndBelongsToManyModel model) { }
/// <summary> /// Visits the has and belongs to many. /// </summary> /// <param name="model">The model.</param> public virtual void VisitHasAndBelongsToMany(HasAndBelongsToManyModel model) { }
public String CreateControl(ActiveRecordModel model, String prefix, HasAndBelongsToManyModel hasAndBelongsModel, object instance) { stringBuilder.Length = 0; PropertyInfo prop = hasAndBelongsModel.Property; prefix += "." + prop.Name; ActiveRecordModel otherModel = ActiveRecordModel.GetModel(hasAndBelongsModel.HasManyAtt.MapType); PrimaryKeyModel keyModel = ObtainPKProperty(otherModel); if (otherModel == null || keyModel == null) { return "Model not found or PK not found"; } object[] source = CommonOperationUtils.FindAll(otherModel.Type); stringBuilder.Append(prop.Name + ": "); stringBuilder.Append("<br/>\r\n"); IDictionary attrs = new HybridDictionary(true); attrs["value"] = keyModel.Property.Name; FormHelper.CheckboxList list = CreateCheckboxList(prefix, source, attrs); foreach(object item in list) { stringBuilder.Append(list.Item()); stringBuilder.Append(item.ToString()); stringBuilder.Append("<br/>\r\n"); } return stringBuilder.ToString(); }
public bool CanHandle(HasAndBelongsToManyModel model) { if (!model.HasManyAtt.Inverse) { return CheckModelAndKeyAreAccessible(model.HasManyAtt.MapType); } return false; }
/// <summary> /// Visits the has and belongs to many. /// </summary> /// <remarks> /// Verify that a link table was specified /// Verify that a key was specified and that it is valid /// Verify that required information was specified /// </remarks> /// <param name="model">The model.</param> public override void VisitHasAndBelongsToMany(HasAndBelongsToManyModel model) { if (model.HasManyAtt.MapType == null) { model.HasManyAtt.MapType = GuessType(null, model.Property.PropertyType); } model.HasManyAtt.RelationType = GuessRelation(model.Property, model.HasManyAtt.RelationType); Type otherend = GuessType(model.HasManyAtt.MapType, model.Property.PropertyType); if (model.HasManyAtt.Table == null) { throw new ActiveRecordException(String.Format( "For a many to many association (HasAndBelongsToMany) we need that you " + "specify the association table - {0}.{1} ", currentModel.Type.Name, model.Property.Name)); } if (model.HasManyAtt.ColumnKey == null && model.HasManyAtt.CompositeKeyColumnKeys == null) { throw new ActiveRecordException(String.Format( "For a many to many association (HasAndBelongsToMany) we need that you " + "specify the ColumnKey or CompositeKeyColumnKeys - which is the column(s) that represents the type {0} " + "on the association table - {0}.{1} ", currentModel.Type.Name, model.Property.Name)); } if (model.HasManyAtt.ColumnKey != null && model.HasManyAtt.CompositeKeyColumnKeys != null) { throw new ActiveRecordException(String.Format( "For a many to many association (HasAndBelongsToMany) there should only be " + "a ColumnKey or an array of CompositeKeyColumnKeys, not both.")); } if (model.HasManyAtt.CompositeKeyColumnKeys != null && model.HasManyAtt.CompositeKeyColumnKeys.Length < 2) { throw new ActiveRecordException(String.Format( "For a many to many association (HasAndBelongsToMany) with a CompositeKey, " + "there must be at least two CompositeKeyColumnKeys - which are the columns that represent the type {0} " + "on the association table - {0}.{1} ", currentModel.Type.Name, model.Property.Name)); } if (model.HasManyAtt.RelationType != RelationType.IdBag && model.HasManyAtt.ColumnRef == null && model.HasManyAtt.CompositeKeyColumnRefs == null) { throw new ActiveRecordException(String.Format( "For a many to many association (HasAndBelongsToMany) we need that you " + "specify the ColumnRef or CompositeKeyColumnRefs - which is the column(s) that represents the other end '{2}' " + "on the association table - {0}.{1} ", currentModel.Type.Name, model.Property.Name, otherend.Name)); } if (model.HasManyAtt.ColumnRef != null && model.HasManyAtt.CompositeKeyColumnRefs != null) { throw new ActiveRecordException(String.Format( "For a many to many association (HasAndBelongsToMany) there should only be " + "a ColumnRef or an array of CompositeKeyColumnRefs, not both.")); } if (model.HasManyAtt.CompositeKeyColumnRefs != null && model.HasManyAtt.CompositeKeyColumnRefs.Length < 2) { throw new ActiveRecordException(String.Format( "For a many to many association (HasAndBelongsToMany) with a CompositeKey, " + "there must be at least two CompositeKeyColumnRefs - which are the columns that represent the other end '{2}' " + "on the association table - {0}.{1} ", currentModel.Type.Name, model.Property.Name, otherend.Name)); } if (model.HasManyAtt.RelationType == RelationType.IdBag && model.CollectionID == null) { throw new ActiveRecordException(String.Format( "For a many to many association (HasAndBelongsToMany) using IDBag, you need " + "to specify a CollectionIDAttribute giving us more details. " + "{0}.{1} ", currentModel.Type.Name, model.Property.Name)); } if (model.HasManyAtt.RelationType == RelationType.Map && model.HasManyAtt.Index == null) { throw new ActiveRecordException(String.Format( "A HasAndBelongsToMany with type Map requires that you specify an 'Index', use the Index property {0}.{1} ", model.Property.DeclaringType.Name, model.Property.Name)); } if (model.HasManyAtt.RelationType == RelationType.List && model.HasManyAtt.Index == null) { throw new ActiveRecordException(String.Format( "A HasAndBelongsToMany with type List requires that you specify an 'Index', use the Index property {0}.{1} ", model.Property.DeclaringType.Name, model.Property.Name)); } base.VisitHasAndBelongsToMany(model); }