public static Type GetEffectiveType(this PropertyInfo prop) => Cache.GetOrAdd(prop, () => { Type type = prop.PropertyType; if (type.IsList()) { type = type.GetGenericArguments().Single(); // // [BelongsTo(typeof(Message), column: "Text")] // public List<string> Messages {get; set;} // // List<ValueType> eseten letrehozunk egy belso nezetet amiben szerepel a join-olt tabla // elsodleges kulcsa is. // if (type.IsValueTypeOrString()) { BelongsToAttribute bta = prop.GetCustomAttribute <BelongsToAttribute>(); type = UnwrappedValueTypeView.CreateView(bta); } } return(type); });
public static Type CreateView(BelongsToAttribute bta) => Cache.GetOrAdd(bta /*jo kulcsnak*/, () => { Type dataTable = bta.OrmType; PropertyInfo pk = dataTable.GetPrimaryKey(), column = bta.OrmType.GetProperty(bta.Column) ?? throw new MissingMemberException(bta.OrmType.Name, bta.Column); // // [View(Base = typeof(Table)), MapFrom(nameof(Column))] // class Table_Column_View // { // [BelongsTo(typeof(Table))] // public int Id {get; set;} // [BelongsTo(typeof(Table))] // public ValueType Column {get; set;} // } // return(CreateView ( new MemberDefinition ( // // A hash kod kell a tipus nevebe mivel ugyanazon oszlophoz tartozo erteklista szerepelhet tobb nezetben is // kulonbozo "required" ertekkel. // $"{dataTable.Name}_{column.Name}_View_{bta.GetHashCode()}", // TODO: FIXME: bta.GetHashCode() gyanusan sokszor ad vissza 0-t dataTable, CustomAttributeBuilderFactory.CreateFrom <MapFromAttribute>(new[] { typeof(string) }, new object[] { column.Name }) ), new[] { // // [BelongsTo(typeof(Table))] // public int Id {get; set;} // new MemberDefinition ( pk.Name, pk.PropertyType, CustomAttributeBuilderFactory.CreateFrom(new BelongsToAttribute(dataTable, bta.Required)) ), // // [BelongsTo(typeof(Table), column: "Column")] // public ValueType Column {get; set;} // new MemberDefinition ( column.Name, column.PropertyType, CustomAttributeBuilderFactory.CreateFrom(new BelongsToAttribute(dataTable, bta.Required)) ) } )); }, nameof(UnwrappedValueTypeView));
public static List <string> GetListColumnNames <T>() { //得到当前类型 Type type = typeof(T); //得到所有属性 PropertyInfo[] properties = type.GetProperties(); List <string> columns = new List <string>(); //遍历属性,并反射出各属性的“注释”,将“注释”命名为列名(通常是中文的) columns.Add("Id,Id"); foreach (PropertyInfo pi in properties) { //反射,得到当前属性的“注释” ChnColAttribute cca = (ChnColAttribute)Attribute.GetCustomAttribute(pi, typeof(ChnColAttribute)); BelongsToAttribute bta = (BelongsToAttribute)Attribute.GetCustomAttribute(pi, typeof(BelongsToAttribute)); //判断“注释”是否为空 string s = string.Empty; if (cca != null) { columns.Add(cca.ChnCol + "," + pi.Name); //向集合中添加当前属性的“注释”(中文的) } else if (bta != null) { columns.Add(pi.Name + "_Id" + "," + pi.Name + "_Id"); } //else // throw new Exception("请为对象的所有属性加上\"注释\"\r\n\r\n示例:[Description(\"注释内容\")]"); } return(columns); }
public static SpellParameterInfo[] Generate(Type type) { List <SpellParameterInfo> infos = new List <SpellParameterInfo>(); StreamDataInfo[] parameters = StreamDataInfo.GetProperties(type); foreach (var param in parameters) { SpellParameterInfo info = new SpellParameterInfo(); Type paramType = param.PropertyInfo.PropertyType; info.ParameterType = GetParamType(paramType); info.Property = param.PropertyInfo; // Add extra parameter info switch (info.ParameterType) { case SpellParameterType.Enum: info.ParameterArgument = paramType.Name; break; case SpellParameterType.BitFlag: info.ParameterArgument = paramType.Name; break; default: info.ParameterArgument = ""; break; } ParameterAttribute attr = info.Property.GetAttribute <ParameterAttribute>(); if (attr != null) { info.ParameterType = attr.ParameterType; info.ParameterArgument = attr.Parameter; } info.Interpolate = param.Attributes.Count(a => a.GetType() == typeof(InterpolateAttribute)) != 0; info.Hide = param.Attributes.Count(a => a.GetType() == typeof(HideAttribute)) != 0; BelongsToAttribute belongsTo = (BelongsToAttribute)param.Attributes.FirstOrDefault(a => a is BelongsToAttribute); if (belongsTo == null) { info.BelongsTo = String.Empty; } else { info.BelongsTo = belongsTo.Value; } if (info.ParameterType == SpellParameterType.Invalid) { throw new Exception(String.Format("Unhandled parameter: {0} -> {1}", type.FullName, param.GetType().Name)); } infos.Add(info); } return(infos.ToArray()); }
public void BelongsTo_ShouldSelect() { IFragmentFactory attr = new BelongsToAttribute(typeof(Goal_Node)); Action <ISqlQuery> action = ConvertToDelegate(bldr => attr.GetFragments(bldr, typeof(View3).GetProperty(nameof(View3.Id)), false)); var mockBuilder = new Mock <ISqlQuery>(MockBehavior.Strict); mockBuilder.Setup(q => q.Select(typeof(Goal_Node).GetProperty(nameof(Goal_Node.Id)), typeof(View3).GetProperty(nameof(View3.Id)))); action.Invoke(mockBuilder.Object); mockBuilder.Verify(q => q.Select(It.IsAny <PropertyInfo>(), It.IsAny <PropertyInfo>()), Times.Once); }
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); }
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 BelongsToModel(PropertyInfo propInfo, BelongsToAttribute belongsToAtt) { this.propInfo = propInfo; this.belongsToAtt = belongsToAtt; }
/// <summary> /// Initializes a new instance of the <see cref="BelongsToModel"/> class. /// </summary> /// <param name="propInfo">The prop info.</param> /// <param name="belongsToAtt">The belongs to att.</param> public BelongsToModel( PropertyInfo propInfo, BelongsToAttribute belongsToAtt ) { this.propInfo = propInfo; this.belongsToAtt = belongsToAtt; }
/// <summary> /// Sets a value from a specific property. /// </summary> /// <exception cref="ActiveRecordAttributeException"></exception> /// <param name="propertyName">string</param> /// <param name="value">object</param> public static void SetValue(this IActiveRecord wrapper, string propertyName, object value) { if (wrapper.IsProxy) { wrapper.FetchUnderlyingObject(); } if (wrapper.Deleted) { throw new ActiveRecordException("Não é possível setar o valor deste atributo, pois o objeto foi deletado."); } var att = wrapper.GetFieldDefinition(typeof(FieldAttribute), propertyName); if (att == null) { throw new ActiveRecordAttributeException(wrapper.GetType(), String.Format("Não foi possível localizar o atributo de campo para a propriedade {0}", propertyName)); } if (att is DomainFieldAttribute) { SetDisplayValue(wrapper, att, value.ToString()); } if (att is BelongsToAttribute) { BelongsToAttribute attribute = att as BelongsToAttribute; if (value == null) { wrapper.UnderlyingObject.set_Value(attribute.ParentValueFieldIndex, DBNull.Value); } else { wrapper.UnderlyingObject.set_Value(attribute.ParentValueFieldIndex, value); } return; } if (att is OneToOneAttribute) { OneToOneAttribute attribute = att as OneToOneAttribute; if (value == null) { wrapper.UnderlyingObject.set_Value(attribute.RelatedAttributeIndex, DBNull.Value); } else { wrapper.UnderlyingObject.set_Value(attribute.RelatedAttributeIndex, value); } return; } // if the field does not have an index, just exit if (att.Index == -1) { return; } // if the field cannot be null, but it is, throw a new exception if (att.NotNullable && value == null) { throw new ActiveRecordException(String.Format("O atributo {0} não pode ser nulo.", att.FieldName)); } if (att.FieldType == esriFieldType.esriFieldTypeBlob) { SetBlobValue(wrapper, att, value); return; } if (value == null) { wrapper.UnderlyingObject.set_Value(att.Index, DBNull.Value); } else { wrapper.UnderlyingObject.set_Value(att.Index, value); } }