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); }
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)); }
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); }
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); }
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); }
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); } } }
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); }
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); }