예제 #1
0
파일: Mapper.cs 프로젝트: MingLu8/Nemo
        private static PropertyMapper GenerateDelegate(Type sourceType, Type targetType)
        {
            var method = new DynamicMethod("Map_" + sourceType.FullName + "_" + targetType.FullName, null, new[] { typeof(object), typeof(object) }, true);
            var il     = method.GetILGenerator();

            var sourceProperties = Reflector.GetAllProperties(sourceType);
            var targetProperties = Reflector.GetAllProperties(targetType);

            var entityMap = MappingFactory.GetEntityMap(targetType);

            var matches = sourceProperties.CrossJoin(targetProperties).Where(t => (t.Item2.Name == t.Item3.Name || t.Item2.Name == MappingFactory.GetPropertyOrColumnName(t.Item3, false, entityMap, false)) &&
                                                                             t.Item2.PropertyType == t.Item3.PropertyType &&
                                                                             t.Item2.PropertyType.IsPublic &&
                                                                             t.Item3.PropertyType.IsPublic
                                                                             //&& (t.Item3.PropertyType.IsValueType || t.Item3.PropertyType == typeof(string))
                                                                             && t.Item2.CanRead && t.Item3.CanWrite);

            foreach (var match in matches)
            {
                il.Emit(OpCodes.Ldarg_1);
                il.EmitCastToReference(targetType);
                il.Emit(OpCodes.Ldarg_0);
                il.EmitCastToReference(sourceType);
                il.Emit(OpCodes.Callvirt, match.Item2.GetGetMethod());
                il.Emit(OpCodes.Callvirt, match.Item3.GetSetMethod());
            }
            il.Emit(OpCodes.Ret);

            var mapper = (PropertyMapper)method.CreateDelegate(typeof(PropertyMapper));

            return(mapper);
        }
예제 #2
0
            static PropertyCache()
            {
                var cachedProperties = PrepareAllProperties <T>();

                Properties = new ReadOnlyDictionary <string, PropertyInfo>(cachedProperties.ToDictionary(p => p.Key, p => p.Value.Item1));
                Positions  = new ReadOnlyDictionary <string, int>(cachedProperties.ToDictionary(p => p.Key, p => p.Value.Item2));

                var map = MappingFactory.GetEntityMap(typeof(T));

                if (map != null)
                {
                    var reflectedProperties = map.Properties.ToDictionary(p => p.Property.PropertyName, p => p.Property);
                    Map = new ReadOnlyDictionary <PropertyInfo, ReflectedProperty>(Properties.Values.ToDictionary(p => p, p =>
                    {
                        ReflectedProperty r;
                        if (!reflectedProperties.TryGetValue(p.Name, out r))
                        {
                            r = new ReflectedProperty(p, cachedProperties[p.Name].Item2);
                        }
                        return(r);
                    }));
                }
                else
                {
                    Map = new ReadOnlyDictionary <PropertyInfo, ReflectedProperty>(Properties.Values.ToDictionary(p => p, p => new ReflectedProperty(p, cachedProperties[p.Name].Item2)));
                }

                NameMap = new ReadOnlyDictionary <string, ReflectedProperty>(Map.ToDictionary(p => p.Key.Name, p => p.Value));
            }
예제 #3
0
        public static async Task <OperationResponse> DeleteAsync <T>(Param[] parameters, string connectionName = null, bool captureException = false, string schema = null, DbConnection connection = null, IConfiguration config = null)
            where T : class
        {
            config ??= ConfigurationFactory.Get <T>();

            var request = new OperationRequest {
                Parameters = parameters, ReturnType = OperationReturnType.NonQuery, ConnectionName = connectionName, Connection = connection, CaptureException = captureException, Configuration = config
            };

            if (config.GenerateDeleteSql)
            {
                string softDeleteColumn = null;
                var    map = MappingFactory.GetEntityMap <T>();
                if (map != null)
                {
                    softDeleteColumn = map.SoftDeleteColumnName;
                }

                if (softDeleteColumn == null)
                {
                    var attr = Reflector.GetAttribute <T, TableAttribute>();
                    if (attr != null)
                    {
                        softDeleteColumn = attr.SoftDeleteColumn;
                    }
                }

                var partition = parameters.Partition(p => p.IsPrimaryKey);
                // if p.IsPrimaryKey is not set then
                // we need to infer it from reflected property
                if (partition.Item1.Count == 0)
                {
                    var propertyMap  = Reflector.GetPropertyMap <T>();
                    var pimaryKeySet = propertyMap.Values.Where(p => p.IsPrimaryKey).ToDictionary(p => p.ParameterName ?? p.PropertyName, p => p.MappedColumnName);
                    partition = parameters.Partition(p =>
                    {
                        if (pimaryKeySet.TryGetValue(p.Name, out var column))
                        {
                            p.Source       = column;
                            p.IsPrimaryKey = true;
                            return(true);
                        }
                        return(false);
                    });
                }

                request.Operation     = SqlBuilder.GetDeleteStatement(typeof(T), partition.Item1, request.Connection != null ? DialectFactory.GetProvider(request.Connection) : DialectFactory.GetProvider(request.ConnectionName ?? config.DefaultConnectionName, config), softDeleteColumn);
                request.OperationType = OperationType.Sql;
            }
            else
            {
                request.Operation     = OperationDelete;
                request.OperationType = OperationType.StoredProcedure;
                request.SchemaName    = schema;
            }
            var response = await ExecuteAsync <T>(request).ConfigureAwait(false);

            return(response);
        }
예제 #4
0
파일: SqlBuilder.cs 프로젝트: MingLu8/Nemo
        internal static string GetTableNameForSql(Type objectType, DialectProvider dialect)
        {
            if (Reflector.IsEmitted(objectType))
            {
                objectType = Reflector.GetInterface(objectType);
            }

            if (AllTables.TryGetValue(Tuple.Create(objectType, dialect), out var tableName))
            {
                return(tableName);
            }

            var map = MappingFactory.GetEntityMap(objectType);

            if (map != null)
            {
                tableName = dialect.IdentifierEscapeStartCharacter + map.TableName + dialect.IdentifierEscapeEndCharacter;
                if (!string.IsNullOrEmpty(map.SchemaName))
                {
                    tableName = dialect.IdentifierEscapeStartCharacter + map.SchemaName + dialect.IdentifierEscapeEndCharacter + "." + tableName;
                }
            }

            if (tableName == null)
            {
                var attr = Reflector.GetAttribute <TableAttribute>(objectType);
                if (attr != null)
                {
                    tableName = dialect.IdentifierEscapeStartCharacter + attr.Name + dialect.IdentifierEscapeEndCharacter;
                    if (!string.IsNullOrEmpty(attr.SchemaName))
                    {
                        tableName = dialect.IdentifierEscapeStartCharacter + attr.SchemaName + dialect.IdentifierEscapeEndCharacter + "." + tableName;
                    }
                }
            }

            if (tableName != null)
            {
                AllTables.TryAdd(Tuple.Create(objectType, dialect), tableName);
                return(tableName);
            }

            tableName = objectType.Name;
            if (objectType.IsInterface && tableName[0] == 'I')
            {
                tableName = tableName.Substring(1);
            }
            tableName = dialect.IdentifierEscapeStartCharacter + tableName + dialect.IdentifierEscapeEndCharacter;

            AllTables.TryAdd(Tuple.Create(objectType, dialect), tableName);

            return(tableName);
        }
예제 #5
0
파일: Mapper.cs 프로젝트: tahiralvi/Nemo
        private static PropertyMapper GenerateIndexerDelegate(Type indexerType, Type targetType, bool ignoreMappings)
        {
            var method = new DynamicMethod("Map_" + indexerType.FullName + "_" + targetType.FullName, null, new[] { typeof(object), typeof(object) }, typeof(Mapper).Module);
            var il     = method.GetILGenerator();

            var targetProperties = Reflector.GetPropertyMap(targetType);
            var entityMap        = MappingFactory.GetEntityMap(targetType);

            var getItem = indexerType.GetMethod("get_Item", new[] { typeof(string) });

            var matches = targetProperties.Where(t => t.Value.IsSelectable && t.Key.PropertyType.IsPublic && t.Key.CanWrite && (t.Value.IsSimpleList || t.Value.IsSimpleType || t.Value.IsBinary));

            foreach (var match in matches)
            {
                var typeConverter = MappingFactory.GetTypeConverter(getItem.ReturnType, match.Key, entityMap);

                if (match.Value.IsSimpleList && typeConverter == null)
                {
                    continue;
                }

                il.Emit(OpCodes.Ldarg_1);
                if (typeConverter.Item1 != null)
                {
                    //	New the converter
                    il.Emit(OpCodes.Newobj, typeConverter.Item1.GetConstructor(Type.EmptyTypes));
                }
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldstr, MappingFactory.GetPropertyOrColumnName(match.Key, ignoreMappings, entityMap, true));
                il.Emit(OpCodes.Callvirt, getItem);
                if (typeConverter.Item1 == null)
                {
                    il.EmitCastToReference(match.Key.PropertyType);
                }
                else
                {
                    //	Call the convert method
                    il.Emit(OpCodes.Callvirt, typeConverter.Item2.GetMethod("ConvertForward"));
                }
                il.EmitCall(OpCodes.Callvirt, match.Key.GetSetMethod(), null);
            }
            il.Emit(OpCodes.Ret);

            var mapper = (PropertyMapper)method.CreateDelegate(typeof(PropertyMapper));

            return(mapper);
        }
예제 #6
0
        private static void DefineProperties(Type objectType, TypeBuilder typeBuilder, FieldInfo field, Type interfaceType, DynamicProxyType proxyType, bool ignoreMappings)
        {
            var entityMap = MappingFactory.GetEntityMap(interfaceType);

            foreach (var property in Reflector.GetAllProperties(interfaceType))
            {
                // check if we can support the wrapping.
                var propertyName   = MappingFactory.GetPropertyOrColumnName(property, ignoreMappings, entityMap, false);
                var objectProperty = objectType != null?objectType.GetProperty(propertyName) : null;

                if (objectProperty != null && ((property.CanRead && !objectProperty.CanRead) || (property.CanWrite && !objectProperty.CanWrite)))
                {
                    throw new InvalidCastException("Can't cast because the property is missing or does not have the required implementation.");
                }

                // check the property types.
                if (objectProperty != null && objectProperty.PropertyType != property.PropertyType)
                {
                    throw new InvalidCastException("Can't cast because property types do not match.");
                }

                // define the property.
                if (proxyType == DynamicProxyType.FullIndexer)
                {
                    DefineIndexerProperty(property, typeBuilder, field, objectType, ignoreMappings, entityMap);
                }
                else if (proxyType == DynamicProxyType.SimpleIndexer && IsWrappable(property, entityMap))
                {
                    DefineIndexerProperty(property, typeBuilder, field, objectType, ignoreMappings, entityMap);
                }
                else if (proxyType == DynamicProxyType.Guard)
                {
                    DefineGuardedProperty(property, typeBuilder, field, objectType, ignoreMappings, entityMap);
                }
                else if (objectProperty != null)
                {
                    DefineProperty(property, typeBuilder, field, objectType, objectProperty);
                }
                else
                {
                    DefineDefaultProperty(property, typeBuilder);
                }
            }
        }
예제 #7
0
파일: DbFactory.cs 프로젝트: MingLu8/Nemo
        private static string GetDefaultConnectionName(Type objectType)
        {
            string connectionName = null;

            if (Reflector.IsEmitted(objectType))
            {
                objectType = Reflector.GetInterface(objectType);
            }

            var map = MappingFactory.GetEntityMap(objectType);

            if (map != null)
            {
                connectionName = map.ConnectionStringName;
            }

            if (connectionName == null)
            {
                var attr = Reflector.GetAttribute <ConnectionAttribute>(objectType, false, true);
                if (attr != null)
                {
                    connectionName = attr.Name;
                }
            }

            if (connectionName == null)
            {
                var attr = Reflector.GetAttribute <ConnectionAttribute>(objectType, true);
                if (attr != null)
                {
                    connectionName = attr.Name;
                }
            }

            return(connectionName ?? ConfigurationFactory.Get(objectType).DefaultConnectionName);
        }
예제 #8
0
파일: Mapper.cs 프로젝트: MingLu8/Nemo
        private static PropertyMapper GenerateIndexerDelegate(Type indexerType, Type targetType, bool autoTypeCoercion)
        {
            var method = new DynamicMethod("Map_" + indexerType.FullName + "_" + targetType.FullName, null, new[] { typeof(object), typeof(object) }, typeof(Mapper).Module);
            var il     = method.GetILGenerator();

            var targetProperties  = Reflector.GetPropertyMap(targetType);
            var entityMap         = MappingFactory.GetEntityMap(targetType);
            var getTypeFromHandle = typeof(Type).GetMethod("GetTypeFromHandle");
            var getDefaultValue   = typeof(System.Activator).GetMethods().FirstOrDefault(m => m.Name == "CreateInstance" && m.GetParameters().Length == 1 && m.GetParameters()[0].ParameterType == typeof(Type));

            var useIndexerMethod = true;

            if (!GetItemMethods.TryGetValue(indexerType, out var getItem) || getItem == null)
            {
                getItem          = indexerType.GetMethod("get_Item", new[] { typeof(string) });
                useIndexerMethod = false;
            }

            var matches = targetProperties.Where(t => t.Value.IsSelectable && t.Key.PropertyType.IsPublic && t.Key.CanWrite && (t.Value.IsSimpleList || t.Value.IsSimpleType || t.Value.IsBinary));

            foreach (var match in matches)
            {
                var typeConverter = MappingFactory.GetTypeConverter(getItem.ReturnType, match.Key, entityMap);

                if (match.Value.IsSimpleList && typeConverter == null)
                {
                    continue;
                }
                typeConverter = MatchTypeConverter(targetType, match.Value, getItem.ReturnType, typeConverter, autoTypeCoercion);

                il.Emit(OpCodes.Ldarg_1);
                if (typeConverter.Item1 != null)
                {
                    //	New the converter
                    il.Emit(OpCodes.Newobj, typeConverter.Item1.GetConstructor(Type.EmptyTypes));
                }

                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldstr, MappingFactory.GetPropertyOrColumnName(match.Key, false, entityMap, true));
                if (!useIndexerMethod)
                {
                    il.Emit(OpCodes.Callvirt, getItem);
                }
                else
                {
                    var propertyType = match.Value.PropertyType;
                    if (propertyType.IsValueType)
                    {
                        var ctor = propertyType.GetConstructor(Type.EmptyTypes);
                        if (ctor != null)
                        {
                            il.Emit(OpCodes.Newobj, ctor);
                            il.BoxIfNeeded(propertyType);
                        }
                        else if (propertyType.IsPrimitive)
                        {
                            if (propertyType == typeof(double))
                            {
                                il.Emit(OpCodes.Ldc_R8, 0.0);
                            }
                            else if (propertyType == typeof(float))
                            {
                                il.Emit(OpCodes.Ldc_R4, 0.0f);
                            }
                            else
                            {
                                il.EmitFastInt(0);
                                if (propertyType == typeof(long) || propertyType == typeof(ulong))
                                {
                                    il.Emit(OpCodes.Conv_I8);
                                }
                            }
                            il.BoxIfNeeded(propertyType);
                        }
                        else
                        {
                            il.Emit(OpCodes.Ldtoken, propertyType);
                            il.Emit(OpCodes.Call, getTypeFromHandle);
                            il.Emit(OpCodes.Call, getDefaultValue);
                        }
                    }
                    else
                    {
                        il.Emit(OpCodes.Ldnull);
                    }
                    il.Emit(OpCodes.Call, getItem);
                }
                if (typeConverter.Item1 == null)
                {
                    il.EmitCastToReference(match.Key.PropertyType);
                }
                else
                {
                    //	Call the convert method
                    il.Emit(OpCodes.Callvirt, typeConverter.Item2.GetMethod("ConvertForward"));
                }
                il.EmitCall(OpCodes.Callvirt, match.Key.GetSetMethod(), null);
            }
            il.Emit(OpCodes.Ret);

            var mapper = (PropertyMapper)method.CreateDelegate(typeof(PropertyMapper));

            return(mapper);
        }