private static SchemaItem FromDataRow(DataRow row) { var result = new SchemaItem(); result.ColumnName = row.Table.Columns.Contains("ColumnName") ? row["ColumnName"].ToType <string>() : null; result.ColumnOrdinal = row.Table.Columns.Contains("ColumnOrdinal") ? row["ColumnOrdinal"].ToType <int?>() : null; result.ColumnSize = row.Table.Columns.Contains("ColumnSize") ? row["ColumnSize"].ToType <int?>() : null; result.NumericPrecision = row.Table.Columns.Contains("NumericPrecision") ? row["NumericPrecision"].ToType <int?>() : null; result.NumericScale = row.Table.Columns.Contains("NumericScale") ? row["NumericScale"].ToType <int?>() : null; result.IsUnique = row.Table.Columns.Contains("IsUnique") ? row["IsUnique"].ToType <bool?>() : null; result.IsKey = row.Table.Columns.Contains("IsKey") ? row["IsKey"].ToType <bool?>() : null; result.BaseServerName = row.Table.Columns.Contains("BaseServerName") ? row["BaseServerName"].ToType <string>() : null; result.BaseCatalogName = row.Table.Columns.Contains("BaseCatalogName") ? row["BaseCatalogName"].ToType <string>() : null; result.BaseColumnName = row.Table.Columns.Contains("BaseColumnName") ? row["BaseColumnName"].ToType <string>() : null; result.BaseSchemaName = row.Table.Columns.Contains("BaseSchemaName") ? row["BaseSchemaName"].ToType <string>() : null; result.BaseTableName = row.Table.Columns.Contains("BaseTableName") ? row["BaseTableName"].ToType <string>() : null; result.DataType = row.Table.Columns.Contains("DataType") ? Type.GetType(row["DataType"].ToString()) : null; result.AllowDbNull = row.Table.Columns.Contains("AllowDBNull") ? row["AllowDBNull"].ToType <bool?>() : null; result.ProviderType = row.Table.Columns.Contains("ProviderType") ? row["ProviderType"].ToType <int?>() : null; result.IsAliased = row.Table.Columns.Contains("IsAliased") ? row["IsAliased"].ToType <bool?>() : null; result.IsExpression = row.Table.Columns.Contains("IsExpression") ? row["IsExpression"].ToType <bool?>() : null; result.IsIdentity = row.Table.Columns.Contains("IsIdentity") ? row["IsIdentity"].ToType <bool?>() : null; result.IsAutoIncrement = row.Table.Columns.Contains("IsAutoIncrement") ? row["IsAutoIncrement"].ToType <bool?>() : null; result.IsRowVersion = row.Table.Columns.Contains("IsRowVersion") ? row["IsRowVersion"].ToType <bool?>() : null; result.IsHidden = row.Table.Columns.Contains("IsHidden") ? row["IsHidden"].ToType <bool?>() : null; result.IsLong = row.Table.Columns.Contains("IsLong") ? row["IsLong"].ToType <bool?>() : null; result.IsReadOnly = row.Table.Columns.Contains("IsReadOnly") ? row["IsReadOnly"].ToType <bool?>() : null; result.ProviderSpecificDataType = row.Table.Columns.Contains("ProviderSpecificDataType") ? Type.GetType(row["ProviderSpecificDataType"].ToString()) : null; result.DataTypeName = row.Table.Columns.Contains("DataTypeName") ? row["DataTypeName"].ToType <string>() : null; return(result); }
/// <summary> /// Geneaate expression with the deserializer /// </summary> /// <typeparam name="T"></typeparam> /// <param name="dataReader"></param> /// <returns></returns> private static Expression<Func<IDataRecord, T>> CreateExpression<T>(IDataReader dataReader) where T : new() { var returnType = typeof(T); var dataReaderParam = Expression.Parameter(typeof(IDataRecord), "dataReader"); var indexProperty = typeof(IDataRecord).GetProperty("Item", new[] { typeof(string) }); if (indexProperty == null) { throw new XyapperException("Failed to get [] property for IDataRecord. Very strange..."); } var readerColumns = SchemaItem.GetSchemas(dataReader).Select(column => column.ColumnName).ToArray(); var constructor = Expression.New(typeof(T)); var assignments = new List<MemberAssignment>(); var properties = returnType.GetProperties(); foreach (var property in properties) { var mappingAttribute = property.GetCustomAttribute<ColumnMappingAttribute>(); var targetColumnName = mappingAttribute != null ? mappingAttribute.ColumnName : property.Name; targetColumnName = Map(readerColumns, targetColumnName); if (string.IsNullOrEmpty(targetColumnName)) continue; var propertyExpression = Expression.Property(dataReaderParam, indexProperty, Expression.Constant(targetColumnName)); Expression valueExpression; if (XyapperManager.UseAdvancedTypeConversions) { var methodInfo = typeof(TypeConverter) .GetMethod(nameof(TypeConverter.ToType), BindingFlags.Public | BindingFlags.Static) ?.MakeGenericMethod(property.PropertyType); valueExpression = Expression.Call(methodInfo ?? throw new XyapperException("Failed to get method ToType<>!"), propertyExpression, Expression.Constant(CultureInfo.InvariantCulture)); } else { var conditionalExpression = Expression.Condition(Expression.Equal(propertyExpression, Expression.Constant(DBNull.Value)), Expression.Constant(null), propertyExpression); valueExpression = Expression.Convert(conditionalExpression, property.PropertyType); } assignments.Add(Expression.Bind(property, valueExpression)); } var block = Expression.MemberInit(constructor, assignments.Cast<MemberBinding>().ToArray()); return Expression.Lambda<Func<IDataRecord, T>>(block, dataReaderParam); }