private object SetHasManyRelationship(object entity, PropertyInfo[] entityProperties, HasManyAttribute attr, ContextEntity contextEntity, Dictionary <string, RelationshipData> relationships, List <ResourceObject> included = null) { var relationshipName = attr.PublicRelationshipName; if (relationships.TryGetValue(relationshipName, out RelationshipData relationshipData)) { if (relationshipData.IsHasMany == false || relationshipData.ManyData == null) { return(entity); } var relatedResources = relationshipData.ManyData.Select(r => { var instance = GetIncludedRelationship(r, included, attr); return(instance); }); var convertedCollection = TypeHelper.ConvertCollection(relatedResources, attr.DependentType); attr.SetValue(entity, convertedCollection); /// todo: as a part of the process of decoupling JADNC (specifically /// through the decoupling IJsonApiContext), we now no longer need to /// store the updated relationship values in this property. For now /// just assigning null as value, will remove this property later as a whole. /// see #512 _jsonApiContext.HasManyRelationshipPointers.Add(attr, null); } return(entity); }
public RelationshipDictionaryTests() { FirstToOneAttr = new HasOneAttribute("firstToOne") { LeftType = typeof(Dummy), RightType = typeof(ToOne), PropertyInfo = typeof(Dummy).GetProperty(nameof(Dummy.FirstToOne)) }; SecondToOneAttr = new HasOneAttribute("secondToOne") { LeftType = typeof(Dummy), RightType = typeof(ToOne), PropertyInfo = typeof(Dummy).GetProperty(nameof(Dummy.SecondToOne)) }; ToManyAttr = new HasManyAttribute("toManies") { LeftType = typeof(Dummy), RightType = typeof(ToMany), PropertyInfo = typeof(Dummy).GetProperty(nameof(Dummy.ToManies)) }; Relationships.Add(FirstToOneAttr, FirstToOnesEntities); Relationships.Add(SecondToOneAttr, SecondToOnesEntities); Relationships.Add(ToManyAttr, ToManiesEntities); AllEntities = new HashSet <Dummy>(FirstToOnesEntities.Union(SecondToOnesEntities).Union(ToManiesEntities).Union(NoRelationshipsEntities)); }
public void HasManyAttribute_Equals_Returns_True_When_Same_Name() { var a = new HasManyAttribute("test"); var b = new HasManyAttribute("test"); Assert.Equal(a, b); }
public void HasManyAttribute_Equals_Returns_False_When_Different_Name() { var a = new HasManyAttribute("test"); var b = new HasManyAttribute("test2"); Assert.NotEqual(a, b); }
/// <inheritdoc /> public QueryLayer ComposeForHasMany <TId>(HasManyAttribute hasManyRelationship, TId leftId, ICollection <IIdentifiable> rightResourceIds) { ArgumentGuard.NotNull(hasManyRelationship, nameof(hasManyRelationship)); ArgumentGuard.NotNull(rightResourceIds, nameof(rightResourceIds)); var leftResourceContext = _resourceContextProvider.GetResourceContext(hasManyRelationship.LeftType); var leftIdAttribute = GetIdAttribute(leftResourceContext); var rightResourceContext = _resourceContextProvider.GetResourceContext(hasManyRelationship.RightType); var rightIdAttribute = GetIdAttribute(rightResourceContext); var rightTypedIds = rightResourceIds.Select(resource => resource.GetTypedId()).ToArray(); var leftFilter = CreateFilterByIds(leftId.AsArray(), leftIdAttribute, null); var rightFilter = CreateFilterByIds(rightTypedIds, rightIdAttribute, null); return(new QueryLayer(leftResourceContext) { Include = new IncludeExpression(new IncludeElementExpression(hasManyRelationship).AsArray()), Filter = leftFilter, Projection = new Dictionary <ResourceFieldAttribute, QueryLayer> { [hasManyRelationship] = new QueryLayer(rightResourceContext) { Filter = rightFilter, Projection = new Dictionary <ResourceFieldAttribute, QueryLayer> { [rightIdAttribute] = null } }, [leftIdAttribute] = null } }); }
private object SetHasManyRelationship(object entity, PropertyInfo[] entityProperties, HasManyAttribute attr, ContextEntity contextEntity, Dictionary <string, RelationshipData> relationships, List <ResourceObject> included = null) { var relationshipName = attr.PublicRelationshipName; if (relationships.TryGetValue(relationshipName, out RelationshipData relationshipData)) { if (relationshipData.IsHasMany == false || relationshipData.ManyData == null) { return(entity); } var relatedResources = relationshipData.ManyData.Select(r => { var instance = GetIncludedRelationship(r, included, attr); return(instance); }); var convertedCollection = TypeHelper.ConvertCollection(relatedResources, attr.Type); attr.SetValue(entity, convertedCollection); _jsonApiContext.RelationshipsToUpdate[attr] = convertedCollection; _jsonApiContext.HasManyRelationshipPointers.Add(attr, convertedCollection); } return(entity); }
public RelationshipDictionaryTests() { FirstToOneAttr = new HasOneAttribute("first-to-one") { PrincipalType = typeof(Dummy), DependentType = typeof(ToOne), InternalRelationshipName = "FirstToOne" }; SecondToOneAttr = new HasOneAttribute("second-to-one") { PrincipalType = typeof(Dummy), DependentType = typeof(ToOne), InternalRelationshipName = "SecondToOne" }; ToManyAttr = new HasManyAttribute("to-manies") { PrincipalType = typeof(Dummy), DependentType = typeof(ToMany), InternalRelationshipName = "ToManies" }; Relationships.Add(FirstToOneAttr, FirstToOnesEntities); Relationships.Add(SecondToOneAttr, SecondToOnesEntities); Relationships.Add(ToManyAttr, ToManiesEntities); AllEntities = new HashSet <Dummy>(FirstToOnesEntities.Union(SecondToOnesEntities).Union(ToManiesEntities).Union(NoRelationshipsEntities)); }
public RelationshipDictionaryTests() { FirstToOneAttr = new HasOneAttribute { PublicName = "firstToOne", LeftType = typeof(Dummy), RightType = typeof(ToOne), Property = typeof(Dummy).GetProperty(nameof(Dummy.FirstToOne)) }; SecondToOneAttr = new HasOneAttribute { PublicName = "secondToOne", LeftType = typeof(Dummy), RightType = typeof(ToOne), Property = typeof(Dummy).GetProperty(nameof(Dummy.SecondToOne)) }; ToManyAttr = new HasManyAttribute { PublicName = "toManies", LeftType = typeof(Dummy), RightType = typeof(ToMany), Property = typeof(Dummy).GetProperty(nameof(Dummy.ToManies)) }; Relationships.Add(FirstToOneAttr, FirstToOnesResources); Relationships.Add(SecondToOneAttr, SecondToOnesResources); Relationships.Add(ToManyAttr, ToManiesResources); AllResources = new HashSet <Dummy>(FirstToOnesResources.Union(SecondToOnesResources).Union(ToManiesResources).Union(NoRelationshipsResources)); }
public RelationshipDictionaryTests() { _firstToOneAttr = new HasOneAttribute { PublicName = "firstToOne", LeftType = typeof(Dummy), RightType = typeof(ToOne), Property = typeof(Dummy).GetProperty(nameof(Dummy.FirstToOne)) }; _secondToOneAttr = new HasOneAttribute { PublicName = "secondToOne", LeftType = typeof(Dummy), RightType = typeof(ToOne), Property = typeof(Dummy).GetProperty(nameof(Dummy.SecondToOne)) }; _toManyAttr = new HasManyAttribute { PublicName = "toManies", LeftType = typeof(Dummy), RightType = typeof(ToMany), Property = typeof(Dummy).GetProperty(nameof(Dummy.ToManies)) }; _relationships.Add(_firstToOneAttr, _firstToOnesResources); _relationships.Add(_secondToOneAttr, _secondToOnesResources); _relationships.Add(_toManyAttr, _toManiesResources); _allResources = new HashSet <Dummy>(_firstToOnesResources.Union(_secondToOnesResources).Union(_toManiesResources).Union(_noRelationshipsResources)); }
public void HasManyAttribute_Does_Not_Equal_HasOneAttribute_With_Same_Name() { RelationshipAttribute a = new HasManyAttribute("test"); RelationshipAttribute b = new HasOneAttribute("test"); Assert.NotEqual(a, b); Assert.NotEqual(b, a); }
public override void VisitHasMany(HasManyModel model) { HasManyAttribute att = model.HasManyAtt; WriteCollection(att.Cascade, att.MapType, att.RelationType, model.Property.Name, model.HasManyAtt.AccessString, att.Table, att.Schema, att.Lazy, att.Inverse, att.OrderBy, att.Where, att.Sort, att.ColumnKey, null, null, att.Index, att.IndexType, att.Cache); }
public override Task OnRemoveFromRelationshipAsync(TResource leftResource, HasManyAttribute hasManyRelationship, ISet <IIdentifiable> rightResourceIds, CancellationToken cancellationToken) { if (ExtensibilityPointsToTrack.HasFlag(ResourceDefinitionExtensibilityPoints.OnRemoveFromRelationshipAsync)) { _hitCounter.TrackInvocation <TResource>(ResourceDefinitionExtensibilityPoints.OnRemoveFromRelationshipAsync); } return(base.OnRemoveFromRelationshipAsync(leftResource, hasManyRelationship, rightResourceIds, cancellationToken)); }
public override async Task OnSetToManyRelationshipAsync(DomainGroup group, HasManyAttribute hasManyRelationship, ISet <IIdentifiable> rightResourceIds, OperationKind operationKind, CancellationToken cancellationToken) { _hitCounter.TrackInvocation <DomainGroup>(ResourceDefinitionHitCounter.ExtensibilityPoint.OnSetToManyRelationshipAsync); if (hasManyRelationship.Property.Name == nameof(DomainGroup.Users)) { HashSet <Guid> rightUserIds = rightResourceIds.Select(resource => (Guid)resource.GetTypedId()).ToHashSet(); List <DomainUser> beforeUsers = await _userSet.Include(user => user.Group).Where(user => rightUserIds.Contains(user.Id)) .ToListAsync(cancellationToken); foreach (DomainUser beforeUser in beforeUsers) { IMessageContent content = null; if (beforeUser.Group == null) { content = new UserAddedToGroupContent { UserId = beforeUser.Id, GroupId = group.Id }; } else if (beforeUser.Group != null && beforeUser.Group.Id != group.Id) { content = new UserMovedToGroupContent { UserId = beforeUser.Id, BeforeGroupId = beforeUser.Group.Id, AfterGroupId = group.Id }; } if (content != null) { _pendingMessages.Add(OutgoingMessage.CreateFromContent(content)); } } if (group.Users != null) { foreach (DomainUser userToRemoveFromGroup in group.Users.Where(user => !rightUserIds.Contains(user.Id))) { var message = OutgoingMessage.CreateFromContent(new UserRemovedFromGroupContent { UserId = userToRemoveFromGroup.Id, GroupId = group.Id }); _pendingMessages.Add(message); } } } }
private static object HasMany(this IActiveRecord wrapper, FieldAttribute relationshipAttribute) { if (!(relationshipAttribute is RelationshipAttribute)) { throw new ActiveRecordAttributeException(wrapper.GetType(), "O atributo não é do tipo HasMany. Não foi possível retornar os objetos relacionados."); } HasManyAttribute hasMany = relationshipAttribute as HasManyAttribute; object[] customAttributes = hasMany.ClassType.GetCustomAttributes(typeof(RepositoryAttribute), true); if (customAttributes.Length != 1) { throw new ActiveRecordAttributeException(hasMany.ClassType, "Não foi possível encontrar o controlador da classe."); } RepositoryAttribute controlled = (RepositoryAttribute)customAttributes[0]; object relatedController = Activator.CreateInstance(controlled.ControllerType); if (relatedController == null) { throw new ActiveRecordAttributeException(controlled.ControllerType, "Não foi possível instanciar o controller."); } PrimaryFieldAttribute pkAtt = wrapper.GetPrimaryKeyDefinition(); if (pkAtt == null) { throw new ActiveRecordAttributeException(wrapper.GetType(), "Não foi possível encontrar a chave primária da classe."); } IQueryFilter filter = new QueryFilterClass(); filter.WhereClause = String.Format(pkAtt.QuoteValue ? "{0} = '{1}'" : "{0} = {1}", hasMany.FieldName, wrapper.UnderlyingObject.get_Value(pkAtt.Index)); if (!String.IsNullOrEmpty(hasMany.OrderBy)) { IQueryFilterDefinition definition = filter as IQueryFilterDefinition; definition.PostfixClause = hasMany.OrderBy; } // prepare the method for invoke // check if the method is lazy or not MethodInfo filterMethod = null; filterMethod = controlled.ControllerType.GetMethod(hasMany.Lazy ? "FilterLazy" : "Filter"); var parameters = new object[1]; parameters[0] = filter; // invoke and return return(filterMethod.Invoke(relatedController, parameters)); }
private bool IsToManyRelationshipBeingCleared(HasManyAttribute hasManyRelationship, TResource leftResource, object valueToAssign) { ICollection <IIdentifiable> newRightResourceIds = _collectionConverter.ExtractResources(valueToAssign); object existingRightValue = hasManyRelationship.GetValue(leftResource); HashSet <IIdentifiable> existingRightResourceIds = _collectionConverter.ExtractResources(existingRightValue).ToHashSet(IdentifiableComparer.Instance); existingRightResourceIds.ExceptWith(newRightResourceIds); return(existingRightResourceIds.Any()); }
private FilterExpression ParseFilterInHas(HasManyAttribute hasManyRelationship) { ResourceContext outerScopeBackup = _resourceContextInScope; Type innerResourceType = hasManyRelationship.RightType; _resourceContextInScope = _resourceContextProvider.GetResourceContext(innerResourceType); FilterExpression filter = ParseFilter(); _resourceContextInScope = outerScopeBackup; return(filter); }
public void HasManyAttribute_Equals_Returns_False_When_Different_Name() { var attribute1 = new HasManyAttribute { PublicName = "test" }; var attribute2 = new HasManyAttribute { PublicName = "test2" }; Assert.NotEqual(attribute1, attribute2); }
public void HasManyAttribute_Equals_Returns_True_When_Same_Name() { var attribute1 = new HasManyAttribute { PublicName = "test" }; var attribute2 = new HasManyAttribute { PublicName = "test" }; Assert.Equal(attribute1, attribute2); }
/// <summary> /// Builds the <see cref="ResourceIdentifierObject"/>s for a HasMany relationship /// </summary> private List <ResourceIdentifierObject> GetRelatedResourceLinkage(HasManyAttribute relationship, IIdentifiable entity) { var relatedEntities = (IEnumerable)relationship.GetValue(entity); var manyData = new List <ResourceIdentifierObject>(); if (relatedEntities != null) { foreach (IIdentifiable relatedEntity in relatedEntities) { manyData.Add(GetResourceIdentifier(relatedEntity)); } } return(manyData); }
public void HasManyAttribute_Does_Not_Equal_HasOneAttribute_With_Same_Name() { RelationshipAttribute attribute1 = new HasManyAttribute { PublicName = "test" }; RelationshipAttribute attribute2 = new HasOneAttribute { PublicName = "test" }; Assert.NotEqual(attribute1, attribute2); Assert.NotEqual(attribute2, attribute1); }
/// <summary> /// Sets a HasMany relationship. /// </summary> private void SetHasManyRelationship(IIdentifiable resource, HasManyAttribute hasManyRelationship, RelationshipEntry relationshipData) { if (relationshipData.ManyData == null) { throw new JsonApiSerializationException("Expected data[] element for to-many relationship.", $"Expected data[] element for '{hasManyRelationship.PublicName}' relationship.", atomicOperationIndex: AtomicOperationIndex); } HashSet <IIdentifiable> rightResources = relationshipData.ManyData.Select(rio => CreateRightResource(hasManyRelationship, rio)) .ToHashSet(IdentifiableComparer.Instance); IEnumerable convertedCollection = CollectionConverter.CopyToTypedCollection(rightResources, hasManyRelationship.Property.PropertyType); hasManyRelationship.SetValue(resource, convertedCollection); AfterProcessField(resource, hasManyRelationship, relationshipData); }
/// <summary> /// Builds the <see cref="ResourceIdentifierObject"/>s for a HasMany relationship. /// </summary> private IList <ResourceIdentifierObject> GetRelatedResourceLinkageForHasMany(HasManyAttribute relationship, IIdentifiable resource) { var value = relationship.GetValue(resource); var relatedResources = TypeHelper.ExtractResources(value); var manyData = new List <ResourceIdentifierObject>(); if (relatedResources != null) { foreach (var relatedResource in relatedResources) { manyData.Add(GetResourceIdentifier(relatedResource)); } } return(manyData); }
public void CanGenerateManyToOneRelation() { Type type = Assembly.GetExecutingAssembly().GetType("Debugging.Tests.ManyToOne_One"); Type type2 = Assembly.GetExecutingAssembly().GetType("Debugging.Tests.ManyToOne_Many"); PropertyInfo property = type.GetProperty("ManyToOne_Manies"); object[] propertyAttributes = property.GetCustomAttributes(typeof(HasManyAttribute), false); Assert.IsTrue(propertyAttributes.Length == 1, "Did not generate HasManyAttribute."); HasManyAttribute attribute = propertyAttributes[0] as HasManyAttribute; Assert.IsTrue(attribute.Table == "Posts"); Assert.IsTrue(attribute.ColumnKey == "post_blogid"); Assert.IsTrue(attribute.Cascade == ManyRelationCascadeEnum.All); Assert.IsTrue(attribute.Cache == CacheEnum.ReadOnly); Assert.IsTrue(attribute.CustomAccess == "TargetCustomAccess"); Assert.IsTrue(attribute.Inverse); Assert.IsTrue(attribute.Lazy); Assert.IsTrue(attribute.OrderBy == "TargetOrderBy"); Assert.IsTrue(attribute.RelationType == RelationType.Bag); Assert.IsTrue(attribute.Schema == "TargetSchema"); Assert.IsTrue(attribute.Where == "TargetWhere"); Assert.IsTrue(attribute.NotFoundBehaviour == NotFoundBehaviour.Exception); Assert.IsTrue(attribute.Element == "TargetElement"); Assert.AreEqual(attribute.MapType, type2); PropertyInfo property2 = type2.GetProperty("SourceProperty"); object[] propertyAttributes2 = property2.GetCustomAttributes(typeof(BelongsToAttribute), false); Assert.IsTrue(propertyAttributes2.Length == 1, "Did not generate BelongsToAttribute."); BelongsToAttribute attribute2 = propertyAttributes2[0] as BelongsToAttribute; Assert.IsTrue(attribute2.Column == "post_blogid"); Assert.IsTrue(attribute2.Cascade == CascadeEnum.All); Assert.IsTrue(attribute2.NotNull == true); Assert.IsTrue(attribute2.CustomAccess == "SourceCustomAccss"); Assert.IsTrue(attribute2.OuterJoin == OuterJoinEnum.True); Assert.IsTrue(attribute2.NotFoundBehaviour == NotFoundBehaviour.Ignore); Assert.IsTrue(attribute2.Unique); Assert.IsFalse(attribute2.Insert); Assert.IsFalse(attribute2.Update); Assert.AreEqual(attribute2.Type, type2); }
/// <summary> /// Sets a HasMany relationship. /// </summary> private void SetHasManyRelationship( IIdentifiable entity, HasManyAttribute attr, RelationshipEntry relationshipData) { if (relationshipData.Data != null) { // if the relationship is set to null, no need to set the navigation property to null: this is the default value. var relatedResources = relationshipData.ManyData.Select(rio => { var relatedInstance = attr.RightType.New <IIdentifiable>(); relatedInstance.StringId = rio.Id; return(relatedInstance); }); var convertedCollection = relatedResources.Cast(attr.RightType); attr.SetValue(entity, convertedCollection); } AfterProcessField(entity, attr, relationshipData); }
/// <summary> /// Sets a HasMany relationship. /// </summary> private void SetHasManyRelationship( IIdentifiable resource, HasManyAttribute attr, RelationshipEntry relationshipData) { if (relationshipData.Data != null) { // if the relationship is set to null, no need to set the navigation property to null: this is the default value. var relatedResources = relationshipData.ManyData.Select(rio => { var relatedInstance = (IIdentifiable)ResourceFactory.CreateInstance(attr.RightType); relatedInstance.StringId = rio.Id; return(relatedInstance); }); var convertedCollection = TypeHelper.CopyToTypedCollection(relatedResources, attr.Property.PropertyType); attr.SetValue(resource, convertedCollection, ResourceFactory); } AfterProcessField(resource, attr, relationshipData); }
public override Task OnRemoveFromRelationshipAsync(DomainGroup group, HasManyAttribute hasManyRelationship, ISet <IIdentifiable> rightResourceIds, CancellationToken cancellationToken) { if (hasManyRelationship.Property.Name == nameof(DomainGroup.Users)) { HashSet <Guid> rightUserIds = rightResourceIds.Select(resource => (Guid)resource.GetTypedId()).ToHashSet(); foreach (DomainUser userToRemoveFromGroup in group.Users.Where(user => rightUserIds.Contains(user.Id))) { var message = OutgoingMessage.CreateFromContent(new UserRemovedFromGroupContent { UserId = userToRemoveFromGroup.Id, GroupId = group.Id }); _pendingMessages.Add(message); } } return(Task.CompletedTask); }
public AffectedEntitiesHelperTests() { FirstToOneAttr = new HasOneAttribute("first-to-one") { PrincipalType = typeof(Dummy), DependentType = typeof(ToOne) }; SecondToOneAttr = new HasOneAttribute("second-to-one") { PrincipalType = typeof(Dummy), DependentType = typeof(ToOne) }; ToManyAttr = new HasManyAttribute("to-manies") { PrincipalType = typeof(Dummy), DependentType = typeof(ToMany) }; Relationships.Add(FirstToOneAttr, FirstToOnesEntities); Relationships.Add(SecondToOneAttr, SecondToOnesEntities); Relationships.Add(ToManyAttr, ToManiesEntities); AllEntities = new HashSet <Dummy>(FirstToOnesEntities.Union(SecondToOnesEntities).Union(ToManiesEntities).Union(NoRelationshipsEntities)); }
public override async Task OnAddToRelationshipAsync(Guid groupId, HasManyAttribute hasManyRelationship, ISet <IIdentifiable> rightResourceIds, CancellationToken cancellationToken) { if (hasManyRelationship.Property.Name == nameof(DomainGroup.Users)) { HashSet <Guid> rightUserIds = rightResourceIds.Select(resource => (Guid)resource.GetTypedId()).ToHashSet(); List <DomainUser> beforeUsers = await _userSet.Include(user => user.Group).Where(user => rightUserIds.Contains(user.Id)) .ToListAsync(cancellationToken); foreach (DomainUser beforeUser in beforeUsers) { IMessageContent content = null; if (beforeUser.Group == null) { content = new UserAddedToGroupContent { UserId = beforeUser.Id, GroupId = groupId }; } else if (beforeUser.Group != null && beforeUser.Group.Id != groupId) { content = new UserMovedToGroupContent { UserId = beforeUser.Id, BeforeGroupId = beforeUser.Group.Id, AfterGroupId = groupId }; } if (content != null) { _pendingMessages.Add(OutgoingMessage.CreateFromContent(content)); } } } }
public Task OnRemoveFromRelationshipAsync <TResource>(TResource leftResource, HasManyAttribute hasManyRelationship, ISet <IIdentifiable> rightResourceIds, CancellationToken cancellationToken) where TResource : class, IIdentifiable { return(Task.CompletedTask); }
public Task OnAddToRelationshipAsync <TResource, TId>(TId leftResourceId, HasManyAttribute hasManyRelationship, ISet <IIdentifiable> rightResourceIds, CancellationToken cancellationToken) where TResource : class, IIdentifiable <TId> { return(Task.CompletedTask); }
///<summary> /// Initializes a new instance of the <see cref="DependentObjectModel"/> class. ///</summary> /// <param name="propInfo">The prop info.</param> /// <param name="hasManyAtt">The nested att.</param> /// <param name="dependentObjectModel">The nested model.</param> public DependentObjectModel(PropertyInfo propInfo, HasManyAttribute hasManyAtt, ActiveRecordModel dependentObjectModel) { this.dependentObjectModel = dependentObjectModel; this.hasManyAtt = hasManyAtt; }
/// <summary> /// Initializes a new instance of the <see cref="HasManyModel"/> class. /// </summary> /// <param name="propInfo">The prop info.</param> /// <param name="hasManyAtt">The has many att.</param> /// <param name="containingTypeModel">The model for the type that contains the HasMany reference.</param> public HasManyModel(PropertyInfo propInfo, HasManyAttribute hasManyAtt, ActiveRecordModel containingTypeModel) { this.hasManyAtt = hasManyAtt; this.propInfo = propInfo; this.containingTypeModel = containingTypeModel; }
/// <summary> /// Initializes a new instance of the <see cref="HasManyModel"/> class. /// </summary> /// <param name="propInfo">The prop info.</param> /// <param name="hasManyAtt">The has many att.</param> public HasManyModel(PropertyInfo propInfo, HasManyAttribute hasManyAtt) { this.hasManyAtt = hasManyAtt; this.propInfo = propInfo; }