public static IEnumerable <Column> GetColumnsForType <T>() where T : PersistenceModel { return(DbHelper.GetColumnsForType(typeof(T))); }
/// <summary> /// Retrieve a collection of columns for the given type /// </summary> /// <param name="entityType">The type to inspect (it is expected to be of type PersistenceModel)</param> /// <returns></returns> public static IEnumerable <Column> GetColumnsForType(Type entityType) { if (!typeof(PersistenceModel).IsAssignableFrom(entityType)) { throw new ArgumentException("Invalid type specified, expecting a type of PersistenceModel", "entityType"); } var columns = new Collection <Column>(); // Sort the properties so the id property is listed first var properties = entityType.GetProperties() .OrderBy(p => p.Name, Comparer <string> .Create((x, y) => { // Ensure id is at the front of the list if (x.ToLowerInvariant() == "id") { return(-1); } if (y.ToLowerInvariant() == "id") { return(1); } return(x.CompareTo(y)); })); foreach (var member in properties) { // Map properties to fields if (member.Name.ToLowerInvariant() == "id") { columns.Add(new Column() { Name = "_Id", // This is the name of the backing variable of the id in the PersistenceModel Type = ColumnType.TEXT, IsPrimaryKey = true, IsForeignKey = false, PropertyPath = "Id" }); } else { // Detect the type of the property down to one of TEXT, NUMERIC, INTEGER, REAL var fieldType = ColumnType.UNKNOWN; var typeCode = Type.GetTypeCode(member.GetUnderlyingType()); var foreignKey = false; var propertyPath = member.Name; var name = member.Name; switch (typeCode) { case TypeCode.Byte: case TypeCode.Int16: case TypeCode.Int32: case TypeCode.Int64: case TypeCode.SByte: case TypeCode.UInt16: case TypeCode.UInt32: case TypeCode.UInt64: fieldType = ColumnType.INTEGER; break; case TypeCode.Char: case TypeCode.String: fieldType = ColumnType.TEXT; break; case TypeCode.Double: case TypeCode.Single: fieldType = ColumnType.REAL; break; case TypeCode.Boolean: case TypeCode.DateTime: case TypeCode.Decimal: fieldType = ColumnType.NUMERIC; break; case TypeCode.Object: // We will store the id of the related entity in this field (Guid format) // but only if this is not the aggregate root child entity and not the aggregate root object if (typeof(PersistenceModel).IsAssignableFrom(member.GetUnderlyingType()) && DbHelper.IsOwner(member)) { fieldType = ColumnType.TEXT; foreignKey = true; name = member.Name + "Id"; propertyPath = member.Name + ".Id"; } break; } if (fieldType != ColumnType.UNKNOWN) { columns.Add(new Column() { Name = name, Type = fieldType, IsPrimaryKey = false, IsForeignKey = foreignKey, PropertyPath = propertyPath }); } } } return(columns); }