internal void LoadType(Type type) { if (type == null || type == typeof(object)) { return; } List <PropertyInfoItem> typeProps = null; List <PropertyInfo> props = null; List <Type> innerTypes = null; //double-check lock pattern; optemized thread-safe if (!properties.ContainsKey(type.FullName) && GetPropertyTypeCategory(type) == PropertyTypeCategory.Class) { lock (locker) { innerTypes = new List <Type>(); if (!properties.ContainsKey(type.FullName) && GetPropertyTypeCategory(type) == PropertyTypeCategory.Class) { typeProps = new List <PropertyInfoItem>(); // props = System.ComponentModel.TypeDescriptor.GetProperties(type.GetProperties); props = type.GetProperties().Where(s => s.GetAccessors(false).Any()).ToList(); foreach (var prop in props) { var atts = prop.GetCustomAttributes(false).ToArray(); if (atts.OfType <NotMappedAttribute>().Any()) { continue; } PropertyTypeCategory propTypeCategory = GetPropertyTypeCategory(prop.PropertyType); PropertyInfoItem propInfoItem = new PropertyInfoItem() { Type = type, TypeCategory = propTypeCategory, Property = prop, PropertyName = prop.Name, PropertyType = prop.PropertyType, IsGenericType = prop.PropertyType == typeof(object), IsReadOnly = !prop.CanWrite }; var primaryKeyAtt = atts.OfType <PrimaryKeyAttribute>().FirstOrDefault(); propInfoItem.IsPrimaryKey = null != primaryKeyAtt; var foreignKeyAtts = atts.OfType <ForeignKeyAttribute>(); if (foreignKeyAtts.Any()) { propInfoItem.ForeignKeys = foreignKeyAtts.Cast <ForeignKeyAttribute>().ToList(); } var parentKeyAtts = atts.OfType <ParentKeyAttribute>(); if (parentKeyAtts.Any()) { propInfoItem.ParentKeys = parentKeyAtts.Cast <ParentKeyAttribute>().ToList(); } PropertyAttribute propertyAtt = atts.OfType <PropertyAttribute>().FirstOrDefault(); if (null != propertyAtt) { propInfoItem.Cascade = propertyAtt.Cascade; propInfoItem.IsAutonumber = propertyAtt.AutoNumber; //propInfoItem.ForceAutoNumber = propertyAtt.OverrideAutoNumber; propInfoItem.IsIndexed = propertyAtt.Indexed; propInfoItem.ValuePosition = propertyAtt.Position; propInfoItem.IdentityIncrement = propertyAtt.IdentityIncrement; propInfoItem.IdentitySeed = propertyAtt.IdentitySeed; } RequiredAttribute requiredAtt = atts.OfType <RequiredAttribute>().FirstOrDefault(); propInfoItem.IsRequired = null != requiredAtt; UniqueKeyAttribute uniqueKeyAtt = atts.OfType <UniqueKeyAttribute>().FirstOrDefault(); propInfoItem.IsUnique = null != uniqueKeyAtt; MarkupAttribute markupAtt = atts.OfType <MarkupAttribute>().FirstOrDefault(); propInfoItem.IsMarkup = null != markupAtt; CryptoAttribute cryptoAtt = atts.OfType <CryptoAttribute>().FirstOrDefault(); propInfoItem.Encryption = (null != cryptoAtt) ? cryptoAtt.Method : CryptoMethod.None; ChildrenAttribute childrenAtt = atts.OfType <ChildrenAttribute>().FirstOrDefault(); //InheritedAttribute inheritedAtt = (InheritedAttribute)atts // .FirstOrDefault(s => s.GetType() == typeof(InheritedAttribute)); if (null != childrenAtt) { propInfoItem.ReferenceType = PropertyReferenceType.Children; propInfoItem.Cascade = CascadeOptions.Delete; propInfoItem.ChildParentProperty = childrenAtt.RemoteParentProperty; } GenericTypePropertyAttribute genericTypeAtt = atts.OfType <GenericTypePropertyAttribute>().FirstOrDefault(); if (prop.PropertyType == typeof(object) && null != genericTypeAtt) { propInfoItem.GenericTypeProperty = genericTypeAtt.Name; } //setting reference type if (propInfoItem.ReferenceType != PropertyReferenceType.Children) { if (propTypeCategory == PropertyTypeCategory.None) { propInfoItem.ReferenceType = PropertyReferenceType.None; } else if (foreignKeyAtts.Any()) { if (prop.PropertyType.GetProperties() .Where(s => s.PropertyType == type && null != s.GetCustomAttribute <ForeignKeyAttribute>(false)).Any()) { propInfoItem.ReferenceType = PropertyReferenceType.SelfForeign; } else { propInfoItem.ReferenceType = PropertyReferenceType.Foreign; } } else if (parentKeyAtts.Any()) { propInfoItem.ReferenceType = PropertyReferenceType.Parent; } else { propInfoItem.ReferenceType = PropertyReferenceType.Reference; // PropertyDescriptorCollection propTypeProps = TypeDescriptor.GetProperties(prop.PropertyType); var propTypeProps = type.GetProperties().Where(s => s.GetAccessors(false).Any()).ToList(); System.Collections.IEnumerator propTypePropsItems = propTypeProps.GetEnumerator(); foreach (var propTypeProp in propTypeProps) { var propTypePropAtts = propTypeProp.GetCustomAttributes(false).ToArray(); if (propTypePropAtts.OfType <PrimaryKeyAttribute>().Any()) { propInfoItem.ReferenceType = PropertyReferenceType.Complex; propInfoItem.Cascade = CascadeOptions.Delete; break; } } } } if (propTypeCategory == PropertyTypeCategory.Array) { propInfoItem.CollectionItemType = prop.PropertyType.GetElementType(); } else if (propTypeCategory == PropertyTypeCategory.GenericCollection) { propInfoItem.CollectionItemType = prop.PropertyType.GetGenericArguments().FirstOrDefault(); } typeProps.Add(propInfoItem); if (prop.PropertyType != type && ( propTypeCategory == PropertyTypeCategory.Class || propTypeCategory == PropertyTypeCategory.Array || propTypeCategory == PropertyTypeCategory.GenericCollection)) { if (prop.PropertyType.IsArray && prop.PropertyType.GetArrayRank() == 1) { innerTypes.Add(prop.PropertyType.GetElementType()); } else if (null != prop.PropertyType.GetTypeInfo().GetInterface("ICollection")) { innerTypes.Add(prop.PropertyType.GetGenericArguments().FirstOrDefault()); } else if (prop.PropertyType.GetTypeInfo().IsClass) { innerTypes.Add(prop.PropertyType); } } } properties.Add(type.FullName, typeProps); //if there is no PrimaryKey find a property with name Id and make it PrimaryKey if (!typeProps.Any(s => s.IsPrimaryKey)) { var primaryKeyProperty = typeProps.FirstOrDefault(s => s.PropertyName == "Id"); if (primaryKeyProperty != null) { primaryKeyProperty.IsPrimaryKey = true; if (primaryKeyProperty.PropertyType != typeof(string)) { primaryKeyProperty.IsAutonumber = true; } } } } } //after loading all PropertyInfoItems validate them CheckReservedKeywords(type); //load types of inner reference type properties foreach (var innerType in innerTypes) { LoadType(innerType); } } //else if (properties.ContainsKey(type.FullName)) //{ // typeProps = Properties(type.FullName).ToList(); // props = System.ComponentModel.TypeDescriptor.GetProperties(type); // foreach (PropertyDescriptor prop in props) // { // var propItems = typeProps.Select(s => s.Property).ToArray(); // if (propItems.Contains(prop)) // continue; // var refType = GetPropertyTypeCategory(prop.PropertyType); // if (refType == PropertyTypeCategory.Class || // refType == PropertyTypeCategory.Array || // refType == PropertyTypeCategory.GenericCollection) // { // if (prop.PropertyType.IsArray && prop.PropertyType.GetArrayRank() == 1) // LoadType(prop.PropertyType.GetElementType()); // else if (null != prop.PropertyType.GetInterface("ICollection")) // LoadType(prop.PropertyType.GetGenericArguments().FirstOrDefault()); // else if (prop.PropertyType.IsClass) // LoadType(prop.PropertyType); // } // } //} }
public T CreateProperty <T>(string name, string caption, IBusinessObjectBase propertyType, PropertyTypeCategory category = PropertyTypeCategory.简单类型) where T : IPropertyExtend { var t = objectSpace.CreateObject <IProperty>(); t.Name = name; t.Caption = caption; t.TypeCategory = category; if (propertyType != null) { t.PropertyType = propertyType; } BusinessObject.Properties.Add(t); return((T)t.ExtendSetting); }