public PocoData(Type t, IMapper mapper, Cache <string, Type> aliasToTypeCache) { _mappingFactory = new MappingFactory(this); AliasToType = aliasToTypeCache; type = t; Mapper = mapper; TableInfo = TableInfo.FromPoco(t); // Call column mapper if (Mapper != null) { Mapper.GetTableInfo(t, TableInfo); } var alias = CreateAlias(type.Name, type); TableInfo.AutoAlias = alias; var index = 0; // Work out bound properties Columns = new Dictionary <string, PocoColumn>(StringComparer.OrdinalIgnoreCase); foreach (var mi in ReflectionUtils.GetFieldsAndPropertiesForClasses(t)) { ColumnInfo ci = ColumnInfo.FromMemberInfo(mi); if (ci.IgnoreColumn) { continue; } var pc = new PocoColumn(); pc.TableInfo = TableInfo; pc.MemberInfo = mi; pc.ColumnName = ci.ColumnName; pc.ResultColumn = ci.ResultColumn; pc.ForceToUtc = ci.ForceToUtc; pc.ComputedColumn = ci.ComputedColumn; pc.ColumnType = ci.ColumnType; pc.ColumnAlias = ci.ColumnAlias; pc.VersionColumn = ci.VersionColumn; pc.VersionColumnType = ci.VersionColumnType; if (Mapper != null && !Mapper.MapMemberToColumn(mi, ref pc.ColumnName, ref pc.ResultColumn)) { continue; } pc.AutoAlias = alias + "_" + index++; // Store it if (!Columns.ContainsKey(pc.ColumnName)) { Columns.Add(pc.ColumnName, pc); } } // Build column list for automatic select QueryColumns = Columns.Where(c => !c.Value.ResultColumn).ToArray(); }
public static Func <object, object> GetConverter(MapperCollection mapper, PocoColumn pc, Type srcType, Type dstType) { Func <object, object> converter = null; // Get converter from the mapper if (mapper != null) { converter = pc != null && pc.MemberInfoData != null?mapper.Find(x => x.GetFromDbConverter(pc.MemberInfoData.MemberInfo, srcType)) : mapper.Find(x => x.GetFromDbConverter(dstType, srcType)); if (converter != null) { return(converter); } } if (pc != null && pc.SerializedColumn) { converter = delegate(object src) { return(DatabaseFactory.ColumnSerializer.Deserialize((string)src, dstType)); }; return(converter); } // Standard DateTime->Utc mapper if (pc != null && pc.ForceToUtc && srcType == typeof(DateTime) && (dstType == typeof(DateTime) || dstType == typeof(DateTime?))) { converter = delegate(object src) { return(new DateTime(((DateTime)src).Ticks, DateTimeKind.Utc)); }; return(converter); } // Forced type conversion including integral types -> enum var underlyingType = UnderlyingTypes.Get(dstType, () => Nullable.GetUnderlyingType(dstType)); if (dstType.GetTypeInfo().IsEnum || (underlyingType != null && underlyingType.GetTypeInfo().IsEnum)) { if (srcType == typeof(string)) { converter = src => EnumMapper.EnumFromString((underlyingType ?? dstType), (string)src); return(converter); } if (IsIntegralType(srcType)) { converter = src => Enum.ToObject((underlyingType ?? dstType), src); return(converter); } } else if (srcType == typeof(string) && (dstType == typeof(Guid) || dstType == typeof(Guid?))) { converter = src => Guid.Parse((string)src); } else if ((!pc?.ValueObjectColumn ?? true) && !dstType.IsAssignableFrom(srcType)) { converter = src => Convert.ChangeType(src, (underlyingType ?? dstType), null); } return(converter); }
private static void PushMemberOntoStack(ILGenerator il, PocoColumn pc) { if (pc.MemberInfo.IsField()) { il.Emit(OpCodes.Stfld, (FieldInfo)pc.MemberInfo); } else { il.Emit(OpCodes.Callvirt, ((PropertyInfo)pc.MemberInfo).GetSetMethodOnDeclaringType()); } }
public PocoData(Type t, IMapper mapper, Cache<string, Type> aliasToTypeCache) { _mappingFactory = new MappingFactory(this); AliasToType = aliasToTypeCache; type = t; Mapper = mapper; TableInfo = TableInfo.FromPoco(t); // Call column mapper if (Mapper != null) Mapper.GetTableInfo(t, TableInfo); var alias = CreateAlias(type.Name, type); TableInfo.AutoAlias = alias; var index = 0; // Work out bound properties Columns = new Dictionary<string, PocoColumn>(StringComparer.OrdinalIgnoreCase); foreach (var mi in ReflectionUtils.GetFieldsAndPropertiesForClasses(t)) { ColumnInfo ci = ColumnInfo.FromMemberInfo(mi); if (ci.IgnoreColumn) continue; var pc = new PocoColumn(); pc.TableInfo = TableInfo; pc.MemberInfo = mi; pc.ColumnName = ci.ColumnName; pc.ResultColumn = ci.ResultColumn; pc.ForceToUtc = ci.ForceToUtc; pc.ComputedColumn = ci.ComputedColumn; pc.ColumnType = ci.ColumnType; pc.ColumnAlias = ci.ColumnAlias; pc.VersionColumn = ci.VersionColumn; pc.VersionColumnType = ci.VersionColumnType; if (Mapper != null && !Mapper.MapMemberToColumn(mi, ref pc.ColumnName, ref pc.ResultColumn)) continue; pc.AutoAlias = alias + "_" + index++; // Store it if (!Columns.ContainsKey(pc.ColumnName)) Columns.Add(pc.ColumnName, pc); } // Build column list for automatic select QueryColumns = Columns.Where(c => !c.Value.ResultColumn).ToArray(); }
private static void SetupValueObject(PocoColumn pc, FastCreate fastCreate) { var memberName = "Value"; var hasIValueObject = pc.MemberInfoData.MemberType.GetTypeWithGenericTypeDefinitionOf(typeof(IValueObject <>)); MemberInfo property = string.IsNullOrEmpty(pc.ValueObjectColumnName) ? pc.MemberInfoData.MemberType.GetProperties().FirstOrDefault(x => x.Name.IndexOf(memberName, StringComparison.OrdinalIgnoreCase) >= 0) ?? pc.MemberInfoData.MemberType.GetProperties().First() : ReflectionUtils.GetFieldsAndProperties(pc.MemberInfoData.MemberType, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).First(x => x.Name == pc.ValueObjectColumnName); var type = hasIValueObject != null?hasIValueObject.GetGenericArguments().First() : property.GetMemberInfoType(); var memberAccessor = hasIValueObject != null ? new MemberAccessor(typeof(IValueObject <>).MakeGenericType(type), memberName) : new MemberAccessor(pc.MemberInfoData.MemberType, property.Name); pc.SetValueObjectAccessors(fastCreate, (target, value) => memberAccessor.Set(target, value), target => memberAccessor.Get(target)); pc.ColumnType = type; }
public static Func <object, object> GetConverter(IMapper mapper, PocoColumn pc, Type srcType, Type dstType) { Func <object, object> converter = null; // Get converter from the mapper if (mapper != null) { converter = pc != null?mapper.GetFromDbConverter(pc.MemberInfo, srcType) : mapper.GetFromDbConverter(dstType, srcType); if (converter != null) { return(converter); } } // Standard DateTime->Utc mapper if (pc != null && pc.ForceToUtc && srcType == typeof(DateTime) && (dstType == typeof(DateTime) || dstType == typeof(DateTime?))) { converter = delegate(object src) { return(new DateTime(((DateTime)src).Ticks, DateTimeKind.Utc)); }; return(converter); } // Forced type conversion including integral types -> enum var underlyingType = _underlyingTypes.Get(dstType, () => Nullable.GetUnderlyingType(dstType)); if (dstType.IsEnum || (underlyingType != null && underlyingType.IsEnum)) { if (srcType == typeof(string)) { converter = src => EnumMapper.EnumFromString((underlyingType ?? dstType), (string)src); return(converter); } if (IsIntegralType(srcType)) { converter = src => Enum.ToObject((underlyingType ?? dstType), src); return(converter); } } else if (!dstType.IsAssignableFrom(srcType)) { converter = src => Convert.ChangeType(src, (underlyingType ?? dstType), null); } return(converter); }
public static Func <object, object> GetConverter(IMapper mapper, PocoColumn pc, Type srcType, Type dstType) { Func <object, object> converter = null; // Get converter from the mapper if (mapper != null) { converter = pc != null?mapper.GetFromDbConverter(pc.PropertyInfo, srcType) : mapper.GetFromDbConverter(dstType, srcType); if (converter != null) { return(converter); } } // Standard DateTime->Utc mapper if (pc != null && pc.ForceToUtc && srcType == typeof(DateTime) && (dstType == typeof(DateTime) || dstType == typeof(DateTime?))) { converter = delegate(object src) { return(new DateTime(((DateTime)src).Ticks, DateTimeKind.Utc)); }; return(converter); } // Forced type conversion including integral types -> enum if (dstType.IsEnum && IsIntegralType(srcType)) { if (srcType != typeof(int)) { converter = src => Convert.ChangeType(src, typeof(int), null); } } else if (!dstType.IsAssignableFrom(srcType)) { if (dstType.IsEnum && srcType == typeof(string)) { converter = src => EnumMapper.EnumFromString(dstType, (string)src); } else { converter = src => Convert.ChangeType(src, dstType, null); } } return(converter); }
public PocoData(Type t, IMapper mapper) { type = t; Mapper = mapper; TableInfo = TableInfo.FromPoco(t); // Call column mapper if (Mapper != null) { Mapper.GetTableInfo(t, TableInfo); } // Work out bound properties Columns = new Dictionary <string, PocoColumn>(StringComparer.OrdinalIgnoreCase); foreach (var mi in ReflectionUtils.GetFieldsAndPropertiesForClasses(t)) { ColumnInfo ci = ColumnInfo.FromMemberInfo(mi); if (ci == null) { continue; } var pc = new PocoColumn(); pc.MemberInfo = mi; pc.ColumnName = ci.ColumnName; pc.ResultColumn = ci.ResultColumn; pc.ForceToUtc = ci.ForceToUtc; pc.ColumnType = ci.ColumnType; if (Mapper != null && !Mapper.MapMemberToColumn(mi, ref pc.ColumnName, ref pc.ResultColumn)) { continue; } // Store it Columns.Add(pc.ColumnName, pc); } // Build column list for automatic select QueryColumns = Columns.Where(c => !c.Value.ResultColumn).Select(c => c.Key).ToArray(); }
public IEnumerable <PocoMemberPlan> GetPocoMembers(ColumnInfo[] columnInfos, List <MemberInfo> memberInfos, string prefix = null) { var capturedMembers = memberInfos.ToArray(); var capturedPrefix = prefix; foreach (var columnInfo in columnInfos) { if (columnInfo.IgnoreColumn) { continue; } var memberInfoType = columnInfo.MemberInfo.GetMemberInfoType(); if (columnInfo.ReferenceType == ReferenceType.Many) { var genericArguments = memberInfoType.GetGenericArguments(); memberInfoType = genericArguments.Any() ? genericArguments.First() : memberInfoType.GetTypeWithGenericTypeDefinitionOf(typeof(IList <>)).GetGenericArguments().First(); } var childrenPlans = new List <PocoMemberPlan>(); TableInfoPlan childTableInfoPlan = null; var members = new List <MemberInfo>(capturedMembers) { columnInfo.MemberInfo }; if (columnInfo.ComplexMapping || columnInfo.ReferenceType != ReferenceType.None) { if (capturedMembers.GroupBy(x => x.GetMemberInfoType()).Any(x => x.Count() >= 2)) { continue; } var childColumnInfos = GetColumnInfos(memberInfoType); if (columnInfo.ReferenceType != ReferenceType.None) { childTableInfoPlan = GetTableInfo(memberInfoType, childColumnInfos, members); } var newPrefix = JoinStrings(capturedPrefix, columnInfo.ReferenceType != ReferenceType.None ? "" : (columnInfo.ComplexPrefix ?? columnInfo.MemberInfo.Name)); childrenPlans.AddRange(GetPocoMembers(childColumnInfos, members, newPrefix)); } MemberInfo capturedMemberInfo = columnInfo.MemberInfo; ColumnInfo capturedColumnInfo = columnInfo; var accessors = GetMemberAccessors(members); var memberType = capturedMemberInfo.GetMemberInfoType(); var isList = IsList(capturedMemberInfo); var listType = GetListType(memberType, isList); var isDynamic = capturedMemberInfo.IsDynamic(); var fastCreate = GetFastCreate(memberType, Mapper, isList, isDynamic); var columnName = GetColumnName(capturedPrefix, capturedColumnInfo.ColumnName ?? capturedMemberInfo.Name); var memberInfoData = new MemberInfoData(capturedMemberInfo); yield return(tableInfo => { var pc = new PocoColumn { ReferenceType = capturedColumnInfo.ReferenceType, TableInfo = tableInfo, MemberInfoData = memberInfoData, MemberInfoChain = members, ColumnName = columnName, ResultColumn = capturedColumnInfo.ResultColumn, ExactColumnNameMatch = capturedColumnInfo.ExactColumnNameMatch, ForceToUtc = capturedColumnInfo.ForceToUtc, ComputedColumn = capturedColumnInfo.ComputedColumn, ComputedColumnType = capturedColumnInfo.ComputedColumnType, ColumnType = capturedColumnInfo.ColumnType, ColumnAlias = capturedColumnInfo.ColumnAlias, VersionColumn = capturedColumnInfo.VersionColumn, VersionColumnType = capturedColumnInfo.VersionColumnType, SerializedColumn = capturedColumnInfo.SerializedColumn, ValueObjectColumn = capturedColumnInfo.ValueObjectColumn, }; if (pc.ValueObjectColumn) { SetupValueObject(pc, fastCreate); } pc.SetMemberAccessors(accessors); var childrenTableInfo = childTableInfoPlan == null ? tableInfo : childTableInfoPlan(); var children = childrenPlans.Select(plan => plan(childrenTableInfo)).ToList(); // Cascade ResultColumn down foreach (var child in children.Where(child => child.PocoColumn != null && pc.ResultColumn)) { child.PocoColumn.ResultColumn = true; } var pocoMember = new PocoMember() { MemberInfoData = memberInfoData, MemberInfoChain = members, IsList = isList, IsDynamic = isDynamic, PocoColumn = capturedColumnInfo.ComplexMapping ? null : pc, ReferenceType = capturedColumnInfo.ReferenceType, ReferenceMemberName = capturedColumnInfo.ReferenceMemberName, PocoMemberChildren = children, }; pocoMember.SetMemberAccessor(accessors[accessors.Count - 1], fastCreate, listType); return pocoMember; }); } }
public virtual object ProcessDefaultMappings(PocoColumn pocoColumn, object value) { return(value); }
private IEnumerable<PocoMemberPlan> GetPocoMembers(MapperCollection mapper, ColumnInfo[] columnInfos, List<MemberInfo> memberInfos, string prefix = null) { var capturedMembers = memberInfos.ToArray(); var capturedPrefix = prefix; foreach (var columnInfo in columnInfos) { if (columnInfo.IgnoreColumn) continue; var memberInfoType = columnInfo.MemberInfo.GetMemberInfoType(); if (columnInfo.ReferenceType == ReferenceType.Many) { var genericArguments = memberInfoType.GetGenericArguments(); memberInfoType = genericArguments.Any() ? genericArguments.First() : memberInfoType.GetTypeWithGenericTypeDefinitionOf(typeof(IList<>)).GetGenericArguments().First(); } var childrenPlans = new PocoMemberPlan[0]; TableInfoPlan childTableInfoPlan = null; var members = new List<MemberInfo>(capturedMembers) { columnInfo.MemberInfo }; if (columnInfo.ComplexMapping || columnInfo.ReferenceType != ReferenceType.None) { if (capturedMembers.GroupBy(x => x.GetMemberInfoType()).Any(x => x.Count() >= 2)) { continue; } var childColumnInfos = GetColumnInfos(memberInfoType); if (columnInfo.ReferenceType != ReferenceType.None) { childTableInfoPlan = GetTableInfo(memberInfoType, childColumnInfos, members); } var newPrefix = JoinStrings(capturedPrefix, columnInfo.ReferenceType != ReferenceType.None ? "" : (columnInfo.ComplexPrefix ?? columnInfo.MemberInfo.Name)); childrenPlans = GetPocoMembers(mapper, childColumnInfos, members, newPrefix).ToArray(); } MemberInfo capturedMemberInfo = columnInfo.MemberInfo; ColumnInfo capturedColumnInfo = columnInfo; var accessors = GetMemberAccessors(members); var memberType = capturedMemberInfo.GetMemberInfoType(); var isList = IsList(capturedMemberInfo); var listType = GetListType(memberType, isList); var isDynamic = capturedMemberInfo.IsDynamic(); var fastCreate = GetFastCreate(memberType, mapper, isList, isDynamic); var columnName = GetColumnName(capturedPrefix, capturedColumnInfo.ColumnName ?? capturedMemberInfo.Name); var memberInfoData = new MemberInfoData(capturedMemberInfo); yield return tableInfo => { var pc = new PocoColumn { ReferenceType = capturedColumnInfo.ReferenceType, TableInfo = tableInfo, MemberInfoData = memberInfoData, MemberInfoChain = members, ColumnName = columnName, ResultColumn = capturedColumnInfo.ResultColumn, ForceToUtc = capturedColumnInfo.ForceToUtc, ComputedColumn = capturedColumnInfo.ComputedColumn, ComputedColumnType = capturedColumnInfo.ComputedColumnType, ColumnType = capturedColumnInfo.ColumnType, ColumnAlias = capturedColumnInfo.ColumnAlias, VersionColumn = capturedColumnInfo.VersionColumn, VersionColumnType = capturedColumnInfo.VersionColumnType, SerializedColumn = capturedColumnInfo.SerializedColumn }; pc.SetMemberAccessors(accessors); var childrenTableInfo = childTableInfoPlan == null ? tableInfo : childTableInfoPlan(); var children = childrenPlans.Select(plan => plan(childrenTableInfo)).ToList(); // Cascade ResultColumn down foreach (var child in children.Where(child => child.PocoColumn != null && pc.ResultColumn)) { child.PocoColumn.ResultColumn = true; } var pocoMember = new PocoMember() { MemberInfoData = memberInfoData, MemberInfoChain = members, IsList = isList, IsDynamic = isDynamic, PocoColumn = capturedColumnInfo.ComplexMapping ? null : pc, ReferenceType = capturedColumnInfo.ReferenceType, ReferenceMemberName = capturedColumnInfo.ReferenceMemberName, PocoMemberChildren = children, }; pocoMember.SetMemberAccessor(accessors[accessors.Count - 1], fastCreate, listType); return pocoMember; }; } }
public static bool TryGetColumnByName(Dictionary <string, PocoColumn> columns, string name, out PocoColumn pc) { // Try to get the column by name directly (works when the poco property name matches the DB column name). var found = (columns.TryGetValue(name, out pc) || columns.TryGetValue(name.Replace("_", ""), out pc)); if (!found) { // Try to get the column by the poco member name (the poco property name is different from the DB column name). pc = columns.Values.Where(c => c.MemberInfo.Name == name).FirstOrDefault(); found = (pc != null); } return(found); }