예제 #1
0
        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);
        }
예제 #2
0
        /// <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);
        }