/// <summary>A Type extension method that gets model definition.</summary> /// <param name="modelType">The modelType to act on.</param> /// <returns>The model definition.</returns> public static ModelDefinition GetModelDefinition(this Type modelType) { ModelDefinition modelDef; if (typeModelDefinitionMap.TryGetValue(modelType, out modelDef)) return modelDef; if (modelType.IsValueType() || modelType == typeof(string)) return null; var modelAliasAttr = modelType.FirstAttribute<AliasAttribute>(); var schemaAttr = modelType.FirstAttribute<SchemaAttribute>(); modelDef = new ModelDefinition { ModelType = modelType, Name = modelType.Name, Alias = modelAliasAttr != null ? modelAliasAttr.Name : null, Schema = schemaAttr != null ? schemaAttr.Name : null }; modelDef.CompositeIndexes.AddRange( modelType.GetCustomAttributes(typeof(CompositeIndexAttribute), true).ToList() .ConvertAll(x => (CompositeIndexAttribute)x)); var objProperties = modelType.GetProperties( BindingFlags.Public | BindingFlags.Instance).ToList(); var hasIdField = CheckForIdField(objProperties); var i = 0; foreach (var propertyInfo in objProperties) { var sequenceAttr = propertyInfo.FirstAttribute<SequenceAttribute>(); var computeAttr= propertyInfo.FirstAttribute<ComputeAttribute>(); var pkAttribute = propertyInfo.FirstAttribute<PrimaryKeyAttribute>(); var decimalAttribute = propertyInfo.FirstAttribute<DecimalLengthAttribute>(); var belongToAttribute = propertyInfo.FirstAttribute<BelongToAttribute>(); var isFirst = i++ == 0; var isPrimaryKey = propertyInfo.Name == OrmLiteConfig.IdField || (!hasIdField && isFirst) || pkAttribute != null; var isNullableType = IsNullableType(propertyInfo.PropertyType); var isNullable = (!propertyInfo.PropertyType.IsValueType && propertyInfo.FirstAttribute<RequiredAttribute>() == null) || isNullableType; var propertyType = isNullableType ? Nullable.GetUnderlyingType(propertyInfo.PropertyType) : propertyInfo.PropertyType; var aliasAttr = propertyInfo.FirstAttribute<AliasAttribute>(); var indexAttr = propertyInfo.FirstAttribute<IndexAttribute>(); var isIndex = indexAttr != null; var isUnique = isIndex && indexAttr.Unique; var stringLengthAttr = propertyInfo.FirstAttribute<StringLengthAttribute>(); var defaultValueAttr = propertyInfo.FirstAttribute<DefaultAttribute>(); var referencesAttr = propertyInfo.FirstAttribute<ReferencesAttribute>(); var foreignKeyAttr = propertyInfo.FirstAttribute<ForeignKeyAttribute>(); if (decimalAttribute != null && stringLengthAttr == null) stringLengthAttr = new StringLengthAttribute(decimalAttribute.Precision); var fieldDefinition = new FieldDefinition { Name = propertyInfo.Name, Alias = aliasAttr != null ? aliasAttr.Name : null, FieldType = propertyType, PropertyInfo = propertyInfo, IsNullable = isNullable, IsPrimaryKey = isPrimaryKey, AutoIncrement = isPrimaryKey && propertyInfo.FirstAttribute<AutoIncrementAttribute>() != null, IsIndexed = isIndex, IsUnique = isUnique, FieldLength = stringLengthAttr != null ? stringLengthAttr.MaximumLength : (int?)null, DefaultValue = defaultValueAttr != null ? defaultValueAttr.DefaultValue : null, ForeignKey = foreignKeyAttr == null ? referencesAttr == null ? null : new ForeignKeyConstraint(referencesAttr.Type) : new ForeignKeyConstraint(foreignKeyAttr.Type, foreignKeyAttr.OnDelete, foreignKeyAttr.OnUpdate, foreignKeyAttr.ForeignKeyName), GetValueFn = propertyInfo.GetPropertyGetterFn(), SetValueFn = propertyInfo.GetPropertySetterFn(), Sequence = sequenceAttr != null ? sequenceAttr.Name : string.Empty, IsComputed = computeAttr != null, ComputeExpression = computeAttr != null ? computeAttr.Expression : string.Empty, Scale = decimalAttribute != null ? decimalAttribute.Scale : (int?)null, BelongToModelName = belongToAttribute != null ? belongToAttribute.BelongToTableType.GetModelDefinition().ModelName : null, }; if (propertyInfo.FirstAttribute<IgnoreAttribute>() != null) modelDef.IgnoredFieldDefinitions.Add(fieldDefinition); else modelDef.FieldDefinitions.Add(fieldDefinition); } modelDef.SqlSelectAllFromTable = "SELECT {0} FROM {1} ".Fmt(OrmLiteConfig.DialectProvider.GetColumnNames(modelDef), OrmLiteConfig.DialectProvider.GetQuotedTableName( modelDef)); Dictionary<Type, ModelDefinition> snapshot, newCache; do { snapshot = typeModelDefinitionMap; newCache = new Dictionary<Type, ModelDefinition>(typeModelDefinitionMap); newCache[modelType] = modelDef; } while (!ReferenceEquals( Interlocked.CompareExchange(ref typeModelDefinitionMap, newCache, snapshot), snapshot)); return modelDef; }
/// <summary>Gets foreign key name.</summary> /// <param name="modelDef"> The model definition.</param> /// <param name="refModelDef"> The reference model definition.</param> /// <param name="NamingStrategy">The naming strategy.</param> /// <param name="fieldDef"> The field definition.</param> /// <returns>The foreign key name.</returns> public string GetForeignKeyName(ModelDefinition modelDef, ModelDefinition refModelDef, INamingStrategy NamingStrategy, FieldDefinition fieldDef) { if(ForeignKeyName.IsNullOrEmpty()) { var modelName = modelDef.IsInSchema ? modelDef.Schema + "_" + NamingStrategy.GetTableName(modelDef.ModelName) : NamingStrategy.GetTableName(modelDef.ModelName); var refModelName = refModelDef.IsInSchema ? refModelDef.Schema + "_" + NamingStrategy.GetTableName(refModelDef.ModelName) : NamingStrategy.GetTableName(refModelDef.ModelName); return string.Format("FK_{0}_{1}_{2}", modelName, refModelName, fieldDef.FieldName); } else { return ForeignKeyName; } }