/// <summary> /// 将一个 <see cref="DataRow"/> 转换为一个 <typeparamref name="T"/> 的对象。 /// </summary> /// <param name="row">一个 <see cref="DataRow"/> 对象。</param> /// <returns>由 <see cref="DataRow"/> 中数据转换成的 <typeparamref name="T"/> 对象实例。</returns> public virtual T Map(DataRow row) { var converter = ConvertManager.GetConverter(typeof(T)); if (converter != null) { return((T)converter.ConvertFrom(row[0], row.Table.Columns[0].DataType.GetDbType())); } return(row[0].To <object, T>()); }
internal static TC ToTypeEx <TS, TC>(this TS value) { var converter = ConvertManager.GetConverter(typeof(TC)); if (converter != null) { return((TC)converter.ConvertFrom(value, typeof(TC).GetDbType())); } return(value.To <TS, TC>()); }
protected override Expression VisitColumn(ColumnExpression column) { ParameterExpression recordWrapper; ParameterExpression dataReader; int ordinal; if (scope != null && scope.TryGetValue(column, out recordWrapper, out dataReader, out ordinal)) { if (!column.Type.IsDbTypeSupported()) { throw new InvalidCastException(SR.GetString(SRKind.InvalidCastPropertyValue, column.Type.FullName)); } //把 ColumnExpression 换成 RecordWrapper.GetInt32(IDataReader, int) 这样的表达式 var dbType = column.MapInfo != null && column.MapInfo.DataType != null ? (DbType)column.MapInfo.DataType : column.Type.GetDbType(); var method = RecordWrapHelper.GetMethodByOrdinal(dbType); Expression expression = Expression.Call(recordWrapper, method, dataReader, Expression.Constant(ordinal)); //先找转换器 var converter = ConvertManager.GetConverter(column.Type); if (converter != null) { //调用ConvertManager.GetConverter var mconverter = Expression.Call(null, MthGetConverter, Expression.Constant(column.Type)); //调用 IValueConverter.ConvertFrom expression = (Expression)Expression.Convert( Expression.Call(mconverter, MthConvert, expression, Expression.Constant(dbType)), column.Type); } else { if (column.Type.IsNullableType()) { //调用 RecordWrapper.IsDbNull 判断值是否为空 expression = (Expression)Expression.Condition( Expression.Call(recordWrapper, MthIsDbNull, dataReader, Expression.Constant(ordinal)), Expression.Convert(Expression.Constant(null), column.Type), Expression.Convert(expression, column.Type)); } else if (column.Type != method.ReturnType) { expression = (Expression)Expression.Convert(expression, column.Type); } } return(expression); } return(column); }
/// <summary> /// 将一个 <see cref="IDataReader"/> 转换为一个 <typeparamref name="T"/> 的对象。 /// </summary> /// <param name="database">当前的 <see cref="IDatabase"/> 对象。</param> /// <param name="reader">一个 <see cref="IDataReader"/> 对象。</param> /// <returns>由当前 <see cref="IDataReader"/> 对象中的数据转换成的 <typeparamref name="T"/> 对象实例。</returns> public virtual T Map(IDatabase database, IDataReader reader) { var value = RecordWrapper == null ? reader[0] : RecordWrapper.GetValue(reader, 0); var converter = ConvertManager.GetConverter(typeof(T)); if (converter != null) { return((T)converter.ConvertFrom(value, reader.GetFieldType(0).GetDbType())); } return(value.To <object, T>()); }
/// <summary> /// 将一个 <see cref="IDataReader"/> 转换为一个 <typeparamref name="T"/> 的对象。 /// </summary> /// <param name="reader">一个 <see cref="IDataReader"/> 对象。</param> /// <returns>由当前 <see cref="IDataReader"/> 对象中的数据转换成的 <typeparamref name="T"/> 对象实例。</returns> public virtual T Map(IDataReader reader) { var index = reader.FieldCount != 1 ? 1 : 0; var value = RecordWrapper == null ? reader[index] : RecordWrapper.GetValue(reader, index); var converter = ConvertManager.GetConverter(typeof(T)); if (converter != null) { return((T)converter.ConvertFrom(value, reader.GetFieldType(index).GetDbType())); } return(value.To <object, T>()); }
/// <summary> /// 使用当前的记录填充数组。 /// </summary> /// <param name="mappings">名称和类型的映射字典。</param> /// <param name="item">当前的数据项。</param> /// <param name="data">数组的数组。</param> /// <param name="batch">当前批次中的索引。</param> private void FillArrayData(IEnumerable <PropertyFieldMapping> mappings, object item, object[][] data, int batch) { mappings.ForEach((m, i) => { var value = m.ValueFunc(item); if (value != null) { var converter = ConvertManager.GetConverter(m.PropertyType); if (converter != null) { value = converter.ConvertTo(value, m.FieldType); } } data[i][batch] = value; }); }
private PropertyValue GetConvertedValue(PropertyMapping mapper, bool isNull, Func <int, object> funcGetValue) { var converter = ConvertManager.GetConverter(mapper.Property.Type); if (converter == null) { throw new NotSupportedException(SR.GetString(SRKind.UnableConvertComplexType, mapper.Property.Type)); } if (isNull) { return(PropertyValue.Empty); } var dbType = mapper.Property.Info.DataType ?? DbType.String; return(PropertyValue.NewValue(converter.ConvertFrom(funcGetValue(mapper.Index), dbType))); }
/// <summary> /// 获取受 <see cref="IValueConverter"/> 支持的数据转换值。 /// </summary> /// <param name="entity"></param> /// <param name="property"></param> /// <returns></returns> private static object GetConvertableValue(IEntity entity, IProperty property) { var value = entity.GetValue(property); if (!PropertyValue.IsEmpty(value)) { //查找属性类型对应的转换器 var converter = ConvertManager.GetConverter(property.Type); if (converter != null && property.Info.DataType != null) { var pvValue = value.GetValue(); return(converter.ConvertTo(pvValue, (DbType)property.Info.DataType)); } return(value.GetValue()); } return(property.Type.GetDefaultValue()); }
/// <summary> /// 使用当前的记录填充数组。 /// </summary> /// <param name="mappings">名称和类型的映射字典。</param> /// <param name="item">当前的数据项。</param> /// <param name="data">数组的数组。</param> /// <param name="batch">当前批次中的索引。</param> private void FillArrayData(IEnumerable <PropertyFieldMapping> mappings, object item, object[][] data, int batch) { var i = 0; foreach (var map in mappings) { var value = map.ValueFunc(item); if (value != null) { var converter = ConvertManager.GetConverter(map.PropertyType); if (converter != null) { value = converter.ConvertTo(value, map.FieldType); } } data[i++][batch] = value; } }
/// <summary> /// 获取受 <see cref="IValueConverter"/> 支持的数据转换值。 /// </summary> /// <param name="entity"></param> /// <param name="property"></param> /// <returns></returns> private static object GetConvertableValue(IEntity entity, IProperty property) { var value = entity.InternalGetValue(property); if (!value.IsNullOrEmpty()) { var converter = ConvertManager.GetConverter(property.Type); if (converter != null) { var storageValue = value.GetStorageValue(); var convertValue = converter.ConvertTo(storageValue, (DbType)property.Info.DataType); return(convertValue); } return(value.GetStorageValue()); } return(property.Type.GetDefaultValue()); }
internal static NamedValueExpression GetNamedValueExpression(string name, Expression value, DbType dbType) { var exp = value; if (exp.NodeType == ExpressionType.Convert) { exp = ((UnaryExpression)value).Operand; } if (exp.NodeType != ExpressionType.Constant) { return(new NamedValueExpression(name, exp)); } IValueConverter converter; if ((converter = ConvertManager.GetConverter(exp.Type)) != null) { exp = Expression.Constant(converter.ConvertTo(((ConstantExpression)exp).Value, dbType)); exp = Expression.Convert(exp, typeof(object)); } return(new NamedValueExpression(name, exp, dbType)); }
/// <summary> /// 根据指定的<see cref="PropertyValue"/> 来设置 <see cref="Parameter"/> 的值。 /// </summary> /// <param name="value"></param> /// <param name="parameter"></param> /// <returns></returns> public static Parameter Parametrization(PropertyValue value, Parameter parameter) { switch (value.StorageType) { case StorageType.Boolean: parameter.Value = value.Boolean; parameter.DbType = DbType.Boolean; break; case StorageType.Byte: parameter.Value = value.Byte; parameter.DbType = DbType.Byte; break; case StorageType.ByteArray: parameter.Value = value.ByteArray; parameter.DbType = DbType.Binary; break; case StorageType.Char: parameter.Value = value.Char; parameter.DbType = DbType.AnsiString; break; case StorageType.DateTime: parameter.Value = value.DateTime; parameter.DbType = DbType.DateTime; break; case StorageType.Decimal: parameter.Value = value.Decimal; parameter.DbType = DbType.Decimal; break; case StorageType.Double: parameter.Value = value.Double; parameter.DbType = DbType.Double; break; case StorageType.Enum: parameter.Value = value.Enum.To <int>(); parameter.DbType = DbType.Int32; break; case StorageType.Guid: parameter.Value = value.Guid; parameter.DbType = DbType.Guid; break; case StorageType.Int16: parameter.Value = value.Int16; parameter.DbType = DbType.Int16; break; case StorageType.Int32: parameter.Value = value.Int32; parameter.DbType = DbType.Int32; break; case StorageType.Int64: parameter.Value = value.Int64; parameter.DbType = DbType.Int64; break; case StorageType.Single: parameter.Value = value.Single; parameter.DbType = DbType.Single; break; case StorageType.String: parameter.Value = value.String; parameter.DbType = DbType.AnsiString; break; case StorageType.TimeSpan: parameter.Value = value.TimeSpan; parameter.DbType = DbType.Time; break; case StorageType.Object: var converter = ConvertManager.GetConverter(value.Object.GetType()); if (converter != null) { var dbType = value.DataType ?? DbType.String; parameter.Value = converter.ConvertTo(value.Object, dbType); parameter.DbType = dbType; } break; } return(parameter); }
private Expression BuildExecuteBatch(BatchCommandExpression batch) { var operation = Parameterize(batch.Operation.Body); var result = _translator.Translate(operation); var namedValues = NamedValueGatherer.Gather(operation); var table = new DataTable(); foreach (var nv in namedValues) { var info = GetPropertyInfoFromExpression(nv.Value); if (info != null) { table.Columns.Add(nv.Name, info.DataType.Value.FromDbType()); } else { table.Columns.Add(nv.Name, DataExpressionRow.CreateType(nv.Value.Type)); } } var parameters = namedValues.ToDictionary(s => s.Name, s => { var expression = s.Value; var info = GetPropertyInfoFromExpression(expression); if (info == null) { return(expression); } if (ConvertManager.GetConverter(expression.Type) != null) { var convExp = Expression.Call(null, MethodCache.GetConverter, Expression.Constant(expression.Type)); expression = Expression.Call(convExp, MethodCache.ConvertTo, expression, Expression.Constant((DbType)info.DataType)); } return((object)Expression.Lambda(expression, batch.Operation.Parameters[1]).Compile()); }); var entities = (IEnumerable)batch.Input.Value; foreach (IEntity entity in entities) { var row = table.NewRow(); foreach (var nv in parameters) { if (nv.Value is Delegate del) { row[nv.Key] = del.DynamicInvoke(entity) ?? DBNull.Value; } else if (nv.Value is Expression exp) { exp = ParameterRewriter.Rewrite(exp, batch.Operation.Parameters[1], entity); var setter = Expression.Lambda(exp, _executor).Compile(); row[nv.Key] = DataExpressionRow.Create(exp.Type, setter); } } table.Rows.Add(row); } Expression plan; if (_isAsync) { _cancelToken = Expression.Parameter(typeof(CancellationToken), "token"); plan = Expression.Call(_executor, MethodCache.DbUpdateAsync, Expression.Constant(table), Expression.Constant((SqlCommand)result.QueryText), Expression.Constant(null, typeof(SqlCommand)), Expression.Constant(null, typeof(SqlCommand)), _cancelToken ); } else { plan = Expression.Call(_executor, MethodCache.DbUpdate, Expression.Constant(table), Expression.Constant((SqlCommand)result.QueryText), Expression.Constant(null, typeof(SqlCommand)), Expression.Constant(null, typeof(SqlCommand)) ); } if (operation.NodeType != (ExpressionType)DbExpressionType.Insert) { return(plan); } return(Expression.Call(typeof(ExecutionBuilder), _isAsync ? nameof(ExecutionBuilder.UpdateEntitiesAsync) : nameof(ExecutionBuilder.UpdateEntities), null, plan, Expression.Constant(table, typeof(DataTable)), Expression.Constant(entities, typeof(IEnumerable)))); }