2323#define USE_CSHARP_SQLITE
2424#endif
2525
26- #if NETFX_CORE || NETCORE
27- #define USE_NEW_REFLECTION_API
28- #endif
29-
3026using System ;
3127using System . Collections ;
3228using System . Diagnostics ;
@@ -1868,29 +1864,29 @@ public TableMapping(Type type, CreateFlags createFlags = CreateFlags.None)
18681864 {
18691865 MappedType = type ;
18701866
1871- #if USE_NEW_REFLECTION_API
1872- var tableAttr = ( TableAttribute ) System . Reflection . CustomAttributeExtensions
1873- . GetCustomAttribute ( type . GetTypeInfo ( ) , typeof ( TableAttribute ) , true ) ;
1874- #else
1875- var tableAttr = ( TableAttribute ) type . GetCustomAttributes ( typeof ( TableAttribute ) , true ) . FirstOrDefault ( ) ;
1876- #endif
1867+ var typeInfo = type . GetTypeInfo ( ) ;
1868+ var tableAttr =
1869+ typeInfo . CustomAttributes
1870+ . Where ( x => x . AttributeType == typeof ( TableAttribute ) )
1871+ . Select ( x => ( TableAttribute ) Orm . InflateAttribute ( x ) )
1872+ . FirstOrDefault ( ) ;
18771873
1878- TableName = tableAttr != null ? tableAttr . Name : MappedType . Name ;
1874+ TableName = ( tableAttr != null && ! string . IsNullOrEmpty ( tableAttr . Name ) ) ? tableAttr . Name : MappedType . Name ;
1875+
1876+ var props = new List < PropertyInfo > ( ) ;
1877+ var baseType = type ;
1878+ while ( baseType != typeof ( object ) ) {
1879+ var ti = baseType . GetTypeInfo ( ) ;
1880+ props . AddRange (
1881+ from p in ti . DeclaredProperties
1882+ where ( ( p . GetMethod != null && p . GetMethod . IsPublic ) || ( p . SetMethod != null && p . SetMethod . IsPublic ) || ( p . GetMethod != null && p . GetMethod . IsStatic ) || ( p . SetMethod != null && p . SetMethod . IsStatic ) )
1883+ select p ) ;
1884+ baseType = ti . BaseType ;
1885+ }
18791886
1880- #if ! USE_NEW_REFLECTION_API
1881- var props = MappedType . GetProperties ( BindingFlags . Public | BindingFlags . Instance | BindingFlags . SetProperty ) ;
1882- #else
1883- var props = from p in MappedType . GetRuntimeProperties ( )
1884- where ( ( p . GetMethod != null && p . GetMethod . IsPublic ) || ( p . SetMethod != null && p . SetMethod . IsPublic ) || ( p . GetMethod != null && p . GetMethod . IsStatic ) || ( p . SetMethod != null && p . SetMethod . IsStatic ) )
1885- select p ;
1886- #endif
18871887 var cols = new List < Column > ( ) ;
18881888 foreach ( var p in props ) {
1889- #if ! USE_NEW_REFLECTION_API
1890- var ignore = p . GetCustomAttributes ( typeof ( IgnoreAttribute ) , true ) . Length > 0 ;
1891- #else
1892- var ignore = p . GetCustomAttributes ( typeof ( IgnoreAttribute ) , true ) . Count ( ) > 0 ;
1893- #endif
1889+ var ignore = p . CustomAttributes . Any ( x => x . AttributeType == typeof ( IgnoreAttribute ) ) ;
18941890 if ( p . CanWrite && ! ignore ) {
18951891 cols . Add ( new Column ( p , createFlags ) ) ;
18961892 }
@@ -2040,10 +2036,12 @@ public class Column
20402036
20412037 public Column ( PropertyInfo prop , CreateFlags createFlags = CreateFlags . None )
20422038 {
2043- var colAttr = ( ColumnAttribute ) prop . GetCustomAttributes ( typeof ( ColumnAttribute ) , true ) . FirstOrDefault ( ) ;
2039+ var colAttr = prop . CustomAttributes . FirstOrDefault ( x => x . AttributeType == typeof ( ColumnAttribute ) ) ;
20442040
20452041 _prop = prop ;
2046- Name = colAttr == null ? prop . Name : colAttr . Name ;
2042+ Name = ( colAttr != null && colAttr . ConstructorArguments . Count > 0 ) ?
2043+ colAttr . ConstructorArguments [ 0 ] . Value ? . ToString ( ) :
2044+ prop . Name ;
20472045 //If this type is Nullable<T> then Nullable.GetUnderlyingType returns the T, otherwise it returns null, so get the actual type instead
20482046 ColumnType = Nullable . GetUnderlyingType ( prop . PropertyType ) ?? prop . PropertyType ;
20492047 Collation = Orm . Collation ( prop ) ;
@@ -2068,7 +2066,7 @@ public Column(PropertyInfo prop, CreateFlags createFlags = CreateFlags.None)
20682066 IsNullable = ! ( IsPK || Orm . IsMarkedNotNull ( prop ) ) ;
20692067 MaxStringLength = Orm . MaxStringLength ( prop ) ;
20702068
2071- StoreAsText = prop . PropertyType . GetTypeInfo ( ) . GetCustomAttribute ( typeof ( StoreAsTextAttribute ) , false ) != null ;
2069+ StoreAsText = prop . PropertyType . GetTypeInfo ( ) . CustomAttributes . Any ( x => x . AttributeType == typeof ( StoreAsTextAttribute ) ) ;
20722070 }
20732071
20742072 public void SetValue ( object obj , object val )
@@ -2081,69 +2079,66 @@ public object GetValue (object obj)
20812079 return _prop . GetValue ( obj , null ) ;
20822080 }
20832081 }
2084- }
2085-
2086- internal class EnumCacheInfo
2087- {
2088- public EnumCacheInfo ( Type type )
2089- {
2090- #if ! USE_NEW_REFLECTION_API
2091- IsEnum = type . IsEnum ;
2092- #else
2093- IsEnum = type . GetTypeInfo ( ) . IsEnum ;
2094- #endif
2095-
2096- if ( IsEnum )
2097- {
2098- // Boxing required to avoid invalid cast exception
2099- EnumValues = Enum . GetValues ( type ) . Cast < object > ( ) . ToDictionary ( Convert . ToInt32 , x => Convert . ToInt32 ( x ) . ToString ( ) ) ;
2100-
2101-
2102- #if ! USE_NEW_REFLECTION_API
2103- StoreAsText = type . GetCustomAttribute ( typeof ( StoreAsTextAttribute ) , false ) != null ;
2104- #else
2105- StoreAsText = type . GetTypeInfo ( ) . GetCustomAttribute ( typeof ( StoreAsTextAttribute ) , false ) != null ;
2106- #endif
2107- }
2108- }
2109-
2110- public bool IsEnum { get ; private set ; }
2111-
2112- public bool StoreAsText { get ; private set ; }
2113-
2114- public Dictionary < int , string > EnumValues { get ; private set ; }
2115- }
2082+ }
21162083
2117- internal static class EnumCache
2118- {
2119- private static readonly Dictionary < Type , EnumCacheInfo > Cache = new Dictionary < Type , EnumCacheInfo > ( ) ;
2084+ class EnumCacheInfo
2085+ {
2086+ public EnumCacheInfo ( Type type )
2087+ {
2088+ var typeInfo = type . GetTypeInfo ( ) ;
21202089
2121- public static EnumCacheInfo GetInfo < T > ( )
2122- {
2123- return GetInfo ( typeof ( T ) ) ;
2124- }
2090+ IsEnum = typeInfo . IsEnum ;
21252091
2126- public static EnumCacheInfo GetInfo ( Type type )
2127- {
2128- lock ( Cache )
2129- {
2130- EnumCacheInfo info = null ;
2131- if ( ! Cache . TryGetValue ( type , out info ) )
2132- {
2133- info = new EnumCacheInfo ( type ) ;
2134- Cache [ type ] = info ;
2135- }
2092+ if ( IsEnum )
2093+ {
2094+ StoreAsText = typeInfo . CustomAttributes . Any ( x => x . AttributeType == typeof ( StoreAsTextAttribute ) ) ;
21362095
2137- return info ;
2138- }
2139- }
2140- }
2096+ if ( StoreAsText ) {
2097+ EnumValues = Enum . GetValues ( type ) . Cast < object > ( ) . ToDictionary ( Convert . ToInt32 , x => x . ToString ( ) ) ;
2098+ }
2099+ else {
2100+ EnumValues = Enum . GetValues ( type ) . Cast < object > ( ) . ToDictionary ( Convert . ToInt32 , x => Convert . ToInt32 ( x ) . ToString ( ) ) ;
2101+ }
2102+ }
2103+ }
2104+
2105+ public bool IsEnum { get ; private set ; }
2106+
2107+ public bool StoreAsText { get ; private set ; }
2108+
2109+ public Dictionary < int , string > EnumValues { get ; private set ; }
2110+ }
2111+
2112+ static class EnumCache
2113+ {
2114+ static readonly Dictionary < Type , EnumCacheInfo > Cache = new Dictionary < Type , EnumCacheInfo > ( ) ;
2115+
2116+ public static EnumCacheInfo GetInfo < T > ( )
2117+ {
2118+ return GetInfo ( typeof ( T ) ) ;
2119+ }
2120+
2121+ public static EnumCacheInfo GetInfo ( Type type )
2122+ {
2123+ lock ( Cache )
2124+ {
2125+ EnumCacheInfo info = null ;
2126+ if ( ! Cache . TryGetValue ( type , out info ) )
2127+ {
2128+ info = new EnumCacheInfo ( type ) ;
2129+ Cache [ type ] = info ;
2130+ }
2131+
2132+ return info ;
2133+ }
2134+ }
2135+ }
21412136
21422137 public static class Orm
21432138 {
2144- public const int DefaultMaxStringLength = 140 ;
2145- public const string ImplicitPkName = "Id" ;
2146- public const string ImplicitIndexSuffix = "Id" ;
2139+ public const int DefaultMaxStringLength = 140 ;
2140+ public const string ImplicitPkName = "Id" ;
2141+ public const string ImplicitIndexSuffix = "Id" ;
21472142
21482143 public static string SqlDecl ( TableMapping . Column p , bool storeDateTimeAsTicks )
21492144 {
@@ -2186,11 +2181,7 @@ public static string SqlType (TableMapping.Column p, bool storeDateTimeAsTicks)
21862181 return storeDateTimeAsTicks ? "bigint" : "datetime" ;
21872182 } else if ( clrType == typeof ( DateTimeOffset ) ) {
21882183 return "bigint" ;
2189- #if ! USE_NEW_REFLECTION_API
2190- } else if ( clrType . IsEnum ) {
2191- #else
21922184 } else if ( clrType . GetTypeInfo ( ) . IsEnum ) {
2193- #endif
21942185 if ( p . StoreAsText )
21952186 return "varchar" ;
21962187 else
@@ -2206,67 +2197,83 @@ public static string SqlType (TableMapping.Column p, bool storeDateTimeAsTicks)
22062197
22072198 public static bool IsPK ( MemberInfo p )
22082199 {
2209- var attrs = p . GetCustomAttributes ( typeof ( PrimaryKeyAttribute ) , true ) ;
2210- #if ! USE_NEW_REFLECTION_API
2211- return attrs . Length > 0 ;
2212- #else
2213- return attrs . Count ( ) > 0 ;
2214- #endif
2200+ return p . CustomAttributes . Any ( x => x . AttributeType == typeof ( PrimaryKeyAttribute ) ) ;
22152201 }
22162202
22172203 public static string Collation ( MemberInfo p )
22182204 {
2219- var attrs = p . GetCustomAttributes ( typeof ( CollationAttribute ) , true ) ;
2220- #if ! USE_NEW_REFLECTION_API
2221- if ( attrs . Length > 0 ) {
2222- return ( ( CollationAttribute ) attrs [ 0 ] ) . Value ;
2223- #else
2224- if ( attrs . Count ( ) > 0 ) {
2225- return ( ( CollationAttribute ) attrs . First ( ) ) . Value ;
2226- #endif
2227- } else {
2228- return string . Empty ;
2229- }
2205+ return
2206+ ( p . CustomAttributes
2207+ . Where ( x => typeof ( CollationAttribute ) == x . AttributeType )
2208+ . Select ( x =>
2209+ {
2210+ var args = x . ConstructorArguments ;
2211+ return args . Count > 0 ? ( ( args [ 0 ] . Value as string ) ?? "" ) : "" ;
2212+ } )
2213+ . FirstOrDefault ( ) ) ?? "" ;
22302214 }
22312215
22322216 public static bool IsAutoInc ( MemberInfo p )
22332217 {
2234- var attrs = p . GetCustomAttributes ( typeof ( AutoIncrementAttribute ) , true ) ;
2235- #if ! USE_NEW_REFLECTION_API
2236- return attrs . Length > 0 ;
2237- #else
2238- return attrs . Count ( ) > 0 ;
2239- #endif
2218+ return p . CustomAttributes . Any ( x => x . AttributeType == typeof ( AutoIncrementAttribute ) ) ;
2219+ }
2220+
2221+ public static FieldInfo GetField ( TypeInfo t , string name )
2222+ {
2223+ var f = t . GetDeclaredField ( name ) ;
2224+ if ( f != null )
2225+ return f ;
2226+ return GetField ( t . BaseType . GetTypeInfo ( ) , name ) ;
2227+ }
2228+
2229+ public static PropertyInfo GetProperty ( TypeInfo t , string name )
2230+ {
2231+ var f = t . GetDeclaredProperty ( name ) ;
2232+ if ( f != null )
2233+ return f ;
2234+ return GetProperty ( t . BaseType . GetTypeInfo ( ) , name ) ;
2235+ }
2236+
2237+ public static object InflateAttribute ( CustomAttributeData x )
2238+ {
2239+ var atype = x . AttributeType ;
2240+ var typeInfo = atype . GetTypeInfo ( ) ;
2241+ var args = x . ConstructorArguments . Select ( a => a . Value ) . ToArray ( ) ;
2242+ var r = Activator . CreateInstance ( x . AttributeType , args ) ;
2243+ foreach ( var arg in x . NamedArguments ) {
2244+ if ( arg . IsField ) {
2245+ GetField ( typeInfo , arg . MemberName ) . SetValue ( r , arg . TypedValue . Value ) ;
2246+ }
2247+ else {
2248+ GetProperty ( typeInfo , arg . MemberName ) . SetValue ( r , arg . TypedValue . Value ) ;
2249+ }
2250+ }
2251+ return r ;
22402252 }
22412253
22422254 public static IEnumerable < IndexedAttribute > GetIndices ( MemberInfo p )
22432255 {
2244- var attrs = p . GetCustomAttributes ( typeof ( IndexedAttribute ) , true ) ;
2245- return attrs . Cast < IndexedAttribute > ( ) ;
2256+ var indexedInfo = typeof ( IndexedAttribute ) . GetTypeInfo ( ) ;
2257+ return
2258+ p . CustomAttributes
2259+ . Where ( x => indexedInfo . IsAssignableFrom ( x . AttributeType . GetTypeInfo ( ) ) )
2260+ . Select ( x => ( IndexedAttribute ) InflateAttribute ( x ) ) ;
22462261 }
22472262
22482263 public static int ? MaxStringLength ( PropertyInfo p )
22492264 {
2250- var attrs = p . GetCustomAttributes ( typeof ( MaxLengthAttribute ) , true ) ;
2251- #if ! USE_NEW_REFLECTION_API
2252- if ( attrs . Length > 0 )
2253- return ( ( MaxLengthAttribute ) attrs [ 0 ] ) . Value ;
2254- #else
2255- if ( attrs . Count ( ) > 0 )
2256- return ( ( MaxLengthAttribute ) attrs . First ( ) ) . Value ;
2257- #endif
2258-
2265+ var attr = p . CustomAttributes . FirstOrDefault ( x => x . AttributeType == typeof ( MaxLengthAttribute ) ) ;
2266+ if ( attr != null )
2267+ {
2268+ var attrv = ( MaxLengthAttribute ) InflateAttribute ( attr ) ;
2269+ return attrv . Value ;
2270+ }
22592271 return null ;
22602272 }
22612273
22622274 public static bool IsMarkedNotNull ( MemberInfo p )
22632275 {
2264- var attrs = p . GetCustomAttributes ( typeof ( NotNullAttribute ) , true ) ;
2265- #if ! USE_NEW_REFLECTION_API
2266- return attrs . Length > 0 ;
2267- #else
2268- return attrs . Count ( ) > 0 ;
2269- #endif
2276+ return p . CustomAttributes . Any ( x => x . AttributeType == typeof ( NotNullAttribute ) ) ;
22702277 }
22712278 }
22722279
@@ -2527,6 +2534,7 @@ object ReadCol (Sqlite3Statement stmt, int index, SQLite3.ColType type, Type clr
25272534 if ( type == SQLite3 . ColType . Null ) {
25282535 return null ;
25292536 } else {
2537+ var clrTypeInfo = clrType . GetTypeInfo ( ) ;
25302538 if ( clrType == typeof ( String ) ) {
25312539 return SQLite3 . ColumnString ( stmt , index ) ;
25322540 } else if ( clrType == typeof ( Int32 ) ) {
@@ -2553,11 +2561,7 @@ object ReadCol (Sqlite3Statement stmt, int index, SQLite3.ColType type, Type clr
25532561 }
25542562 } else if ( clrType == typeof ( DateTimeOffset ) ) {
25552563 return new DateTimeOffset ( SQLite3 . ColumnInt64 ( stmt , index ) , TimeSpan . Zero ) ;
2556- #if ! USE_NEW_REFLECTION_API
2557- } else if ( clrType . IsEnum ) {
2558- #else
2559- } else if ( clrType . GetTypeInfo ( ) . IsEnum ) {
2560- #endif
2564+ } else if ( clrTypeInfo . IsEnum ) {
25612565 if ( type == SQLite3 . ColType . Text )
25622566 {
25632567 var value = SQLite3 . ColumnString ( stmt , index ) ;
@@ -3042,30 +3046,14 @@ private CompileResult CompileExpr (Expression expr, List<object> queryArgs)
30423046 //
30433047 object val = null ;
30443048
3045- #if ! USE_NEW_REFLECTION_API
3046- if ( mem . Member . MemberType == MemberTypes . Property ) {
3047- #else
30483049 if ( mem . Member is PropertyInfo ) {
3049- #endif
30503050 var m = ( PropertyInfo ) mem . Member ;
30513051 val = m . GetValue ( obj , null ) ;
3052- #if ! USE_NEW_REFLECTION_API
3053- } else if ( mem . Member . MemberType == MemberTypes . Field ) {
3054- #else
30553052 } else if ( mem . Member is FieldInfo ) {
3056- #endif
3057- #if SILVERLIGHT
3058- val = Expression . Lambda ( expr ) . Compile ( ) . DynamicInvoke ( ) ;
3059- #else
30603053 var m = ( FieldInfo ) mem . Member ;
30613054 val = m . GetValue ( obj ) ;
3062- #endif
30633055 } else {
3064- #if ! USE_NEW_REFLECTION_API
3065- throw new NotSupportedException ( "MemberExpr: " + mem . Member . MemberType ) ;
3066- #else
3067- throw new NotSupportedException ( "MemberExpr: " + mem . Member . DeclaringType ) ;
3068- #endif
3056+ throw new NotSupportedException ( "MemberExpr: " + mem . Member . GetType ( ) ) ;
30693057 }
30703058
30713059 //
0 commit comments