/// <summary> /// 将 <paramref name="other"/> 的属性复制到 <paramref name="source"/> 中。 /// </summary> /// <typeparam name="TSource"></typeparam> /// <param name="source"></param> /// <param name="other"></param> /// <returns></returns> public static TSource CloneFrom <TSource>(this TSource source, object other) { if (other == null) { return(source); } TypeDescriptorUtility.AddDefaultDynamicProvider(); var sourceProperties = TypeDescriptor.GetProperties(source); var otherProperties = TypeDescriptor.GetProperties(other); var sourceLazy = source as ILazyManager; var otherLazy = other as ILazyManager; foreach (PropertyDescriptor p in otherProperties) { if (otherLazy != null && !otherLazy.IsValueCreated(p.Name)) { continue; } var sp = sourceProperties.Find(p.Name, true); if (sp != null) { var value = p.GetValue(other); if (value != null) { sp.SetValue(source, value.ToType(sp.PropertyType)); } } } return(source); }
/// <summary> /// 获取 List 中属性名和 DbType 的映射。 /// </summary> /// <param name="item">元素。</param> /// <returns></returns> protected IList <PropertyFieldMapping> GetNameTypeMapping(object item) { var result = new List <PropertyFieldMapping>(); #if !NET35 && !NETSTANDARD2_0 TypeDescriptorUtility.AddDefaultDynamicProvider(); #endif var resolver = item as IPropertyFieldMappingResolver; if (resolver != null) { return(resolver.GetDbMapping().ToList()); } foreach (PropertyDescriptor pd in TypeDescriptor.GetProperties(item)) { if (pd.PropertyType == null) { throw new InvalidOperationException(SR.GetString(SRKind.PropertyTypeIsNull, item.GetType(), pd.Name)); } result.Add(new PropertyFieldMapping(pd.Name, pd.Name, pd.PropertyType, pd.PropertyType.GetDbType()) { ValueFunc = o => pd.GetValue(o) }); } return(result); }
/// <summary> /// 将一个匿名类型的对象转换为类型为 <see cref="ExpandoObject"/> 的动态对象。使用 <see cref="DynamicObjectTypeDescriptionProvider"/> 类型进行元数据补充。 /// </summary> /// <param name="source">一个匿名类型对象。</param> /// <returns>如果 <paramref name="source"/> 为非匿名类型对象,则为其自身。</returns> public static dynamic ToDynamic(this object source) { if (source == null || source is ExpandoObject) { return(source); } var type = source.GetType(); if (!type.IsAnonymousType()) { return(source); } var expando = new ExpandoObject(); var dictionary = (IDictionary <string, object>)expando; TypeDescriptorUtility.AddDefaultDynamicProvider(); foreach (PropertyDescriptor pd in TypeDescriptor.GetProperties(source)) { dictionary.Add(pd.Name, pd.GetValue(source)); } return(expando); }
private static DataTable ParseFromEnumerable(IEnumerable enumerable) { TypeDescriptorUtility.AddDefaultDynamicProvider(); var enumerator = enumerable.GetEnumerator(); var table = new DataTable(); var flag = new AssertFlag(); PropertyDescriptorCollection properties = null; while (enumerator.MoveNext()) { var current = enumerator.Current; if (flag.AssertTrue()) { properties = TypeDescriptor.GetProperties(current); foreach (PropertyDescriptor pro in properties) { table.Columns.Add(pro.Name, pro.PropertyType.GetNonNullableType()); } } var data = new object[properties.Count]; for (var i = 0; i < data.Length; i++) { data[i] = properties[i].GetValue(current) ?? DBNull.Value; } table.Rows.Add(data); } return(table); }
private static Delegate BuildCloneToDelegate(object obj, Type conversionType, ConvertMapper mapper) { var sourceType = obj.GetType(); var bindings = new List <MemberBinding>(); var parExp = Expression.Parameter(sourceType, "s"); #if !NET35 TypeDescriptorUtility.AddDefaultDynamicProvider(); var @dynamic = obj as IDynamicMetaObjectProvider; if (@dynamic != null) { GetDynamicMemberBindings(@dynamic, conversionType, parExp, bindings, mapper); } else { GetGeneralMemberBindings(obj, sourceType, conversionType, parExp, bindings, mapper); } #else GetGeneralMemberBindings(obj, sourceType, conversionType, parExp, bindings, mapper); #endif var expExp = Expression.New(conversionType); var mbrInitExp = Expression.MemberInit(expExp, bindings); var funcType = typeof(Func <,>).MakeGenericType(sourceType, conversionType); var lambda = Expression.Lambda(funcType, mbrInitExp, parExp); return(lambda.Compile()); }
/// <summary> /// 初始化对象访问器。 /// </summary> /// <param name="list"></param> private void InitAccessories(SqlBulkCopy bulk, IEnumerable <T> list) { var e = list.GetEnumerator(); if (!e.MoveNext()) { return; } _hasRows = true; if (e.Current is IPropertyFieldMappingResolver resolver) { foreach (var map in resolver.GetDbMapping()) { bulk.ColumnMappings.Add(_values.Count, map.FieldName); _values.Add(map.ValueFunc); } } else { TypeDescriptorUtility.AddDefaultDynamicProvider(); foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(e.Current)) { if (property.PropertyType.IsDbTypeSupported()) { bulk.ColumnMappings.Add(_values.Count, property.Name); _values.Add(o => property.GetValue(o)); } } } }
/// <summary> /// 异步的,执行查询文本并将结果并返回动态序列。 /// </summary> /// <param name="queryCommand">查询命令。</param> /// <param name="segment">数据分段对象。</param> /// <param name="parameters">查询参数集合。</param> /// <param name="cancellationToken">取消操作的通知。</param> /// <returns>一个动态对象的枚举器。</returns> public virtual async Task <IEnumerable <dynamic> > ExecuteEnumerableAsync(IQueryCommand queryCommand, IDataSegment segment = null, ParameterCollection parameters = null, CancellationToken cancellationToken = default) { Guard.ArgumentNull(queryCommand, nameof(queryCommand)); cancellationToken.ThrowIfCancellationRequested(); var result = new List <dynamic>(); using var reader = (InternalDataReader) await ExecuteReaderAsync(queryCommand, segment, parameters, CommandBehavior.Default, cancellationToken); var wrapper = Provider.GetService <IRecordWrapper>(); TypeDescriptorUtility.AddDefaultDynamicProvider(); while (await reader.ReadAsync(cancellationToken)) { var expando = new ExpandoObject(); var dictionary = (IDictionary <string, object>)expando; for (int i = 0, n = reader.FieldCount; i < n; i++) { var name = wrapper.GetFieldName(reader, i); if (name.Equals("ROW_NUM")) { continue; } dictionary.Add(wrapper.GetFieldName(reader, i), RecordWrapHelper.GetValue(wrapper, reader, i)); } result.Add(expando); } return(result); }
/// <summary> /// 根据自定义的SQL语句查询返回一组动态对象。 /// </summary> /// <param name="queryCommand">查询命令。</param> /// <param name="segment">数据分段对象。</param> /// <param name="parameters">查询参数集合。</param> /// <returns>一个动态对象的枚举器。</returns> public virtual IEnumerable <dynamic> ExecuteEnumerable(IQueryCommand queryCommand, IDataSegment segment = null, ParameterCollection parameters = null) { Guard.ArgumentNull(queryCommand, nameof(queryCommand)); using var reader = ExecuteReader(queryCommand, segment, parameters, CommandBehavior.Default); var wrapper = Provider.GetService <IRecordWrapper>(); TypeDescriptorUtility.AddDefaultDynamicProvider(); while (reader.Read()) { var expando = new ExpandoObject(); var dictionary = (IDictionary <string, object>)expando; for (int i = 0, n = reader.FieldCount; i < n; i++) { var name = wrapper.GetFieldName(reader, i); if (name.Equals("ROW_NUM")) { continue; } dictionary.Add(wrapper.GetFieldName(reader, i), RecordWrapHelper.GetValue(wrapper, reader, i)); } yield return(expando); } }
/// <summary> /// 根据自定义的SQL语句查询返回一组动态对象。 /// </summary> /// <param name="queryCommand">查询命令。</param> /// <param name="segment">数据分段对象。</param> /// <param name="parameters">查询参数集合。</param> /// <returns>一个动态对象的枚举器。</returns> public virtual IEnumerable <object> ExecuteEnumerable(IQueryCommand queryCommand, IDataSegment segment = null, ParameterCollection parameters = null) { Guard.ArgumentNull(queryCommand, "queryCommand"); using (var reader = ExecuteReader(queryCommand, segment, parameters)) { var wrapper = Provider.GetService <IRecordWrapper>(); #if !N35 && DYNAMIC TypeDescriptorUtility.AddDefaultDynamicProvider(); while (reader.Read()) { var expando = new ExpandoObject(); var dictionary = (IDictionary <string, object>)expando; for (var i = 0; i < reader.FieldCount; i++) { dictionary.Add(wrapper.GetFieldName(reader, i), RecordWrapHelper.GetValue(wrapper, reader, i)); } yield return(expando); } #else var builder = new DataReaderTypeBuilder(reader); var elementType = builder.CreateType(); while (reader.Read()) { yield return(elementType.New(reader, wrapper)); } #endif } }
/// <summary> /// 异步的,执行查询文本并将结果并返回动态序列。 /// </summary> /// <param name="queryCommand">查询命令。</param> /// <param name="segment">数据分段对象。</param> /// <param name="parameters">查询参数集合。</param> /// <param name="cancellationToken">取消操作的通知。</param> /// <returns>一个动态对象的枚举器。</returns> public virtual async IAsyncEnumerable <dynamic> ExecuteEnumerableAsync(IQueryCommand queryCommand, IDataSegment segment = null, ParameterCollection parameters = null, CancellationToken cancellationToken = default) { Guard.ArgumentNull(queryCommand, nameof(queryCommand)); using (var reader = (DbDataReader)(await ExecuteReaderAsync(queryCommand, segment, parameters, cancellationToken))) { var wrapper = Provider.GetService <IRecordWrapper>(); TypeDescriptorUtility.AddDefaultDynamicProvider(); while (await reader.ReadAsync(cancellationToken)) { var expando = new ExpandoObject(); var dictionary = (IDictionary <string, object>)expando; for (var i = 0; i < reader.FieldCount; i++) { var name = wrapper.GetFieldName(reader, i); if (name.Equals("ROW_NUM")) { continue; } dictionary.Add(wrapper.GetFieldName(reader, i), RecordWrapHelper.GetValue(wrapper, reader, i)); } yield return(expando); } } }
protected override bool OnCanExecute(object parameter) { if (parameter is ITypeDescriptor descriptor) { if (TypeDescriptorUtility.IsBeingEdited(this.authenticator, descriptor) == false) { return(false); } return(TypeDescriptorUtility.IsBeingEditedClient(this.authenticator, descriptor) || this.authenticator.Authority == Authority.Admin); } return(false); }
/// <summary> /// 使用另一个对象对源对象进行扩展,这类似于 jQuery 中的 extend 方法。 /// </summary> /// <param name="source">源对象。</param> /// <param name="other">用于扩展的另一个对象。</param> /// <returns></returns> public static object Extend(this object source, object other) { if (source == null) { return(other); } if (other == null) { return(source); } TypeDescriptorUtility.AddDefaultDynamicProvider(); var sourceProperties = TypeDescriptor.GetProperties(source); var otherProperties = TypeDescriptor.GetProperties(other); var expando = new ExpandoObject(); var dictionary = (IDictionary <string, object>)expando; var sourceLazy = source as ILazyManager; var otherLazy = other as ILazyManager; foreach (PropertyDescriptor p in sourceProperties) { if (sourceLazy != null && !sourceLazy.IsValueCreated(p.Name)) { continue; } dictionary.Add(p.Name, p.GetValue(source)); } foreach (PropertyDescriptor p in otherProperties) { if (otherLazy != null && !otherLazy.IsValueCreated(p.Name)) { continue; } if (!dictionary.ContainsKey(p.Name)) { dictionary.Add(p.Name, p.GetValue(other)); } } return(expando); }
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (Authenticator.Current == null) { return(value); } if (parameter == null) { parameter = this.PropertyName; } if (value != null && parameter is string propertyName) { if (value is ITypeDescriptor descriptor) { if (propertyName == IsBeingEdited) { return(TypeDescriptorUtility.IsBeingEdited(Authenticator.Current, descriptor)); } else if (propertyName == IsContentEditor) { throw new NotImplementedException(); //return TypeDescriptorUtility.IsContentEditor(Authenticator.Current, descriptor); } else if (propertyName == IsFlag) { return(TypeDescriptorUtility.IsFlag(Authenticator.Current, descriptor)); } } else { var prop = value.GetType().GetProperty(propertyName); if (prop != null) { return(prop.GetValue(value)); } } } return(value); }
/// <summary> /// 使用另一个对象对源对象进行扩展,生成类型 <typeparamref name="TTarget"/> 的对象。 /// </summary> /// <typeparam name="TTarget"></typeparam> /// <param name="source">源对象。</param> /// <param name="other">用于扩展的另一个对象。</param> /// <returns></returns> public static TTarget ExtendAs <TTarget>(this object source, object other) { var target = source.To <TTarget>(); TypeDescriptorUtility.AddDefaultDynamicProvider(); var sourceProperties = TypeDescriptor.GetProperties(target); var otherProperties = TypeDescriptor.GetProperties(other); foreach (PropertyDescriptor p in otherProperties) { var targetProperty = sourceProperties[p.Name]; if (targetProperty != null && !targetProperty.IsReadOnly && targetProperty.PropertyType == p.PropertyType) { var value = p.GetValue(other); targetProperty.SetValue(target, value); } } return(target); }
private static Delegate BuildMapToDelegate(object source, object target, Type conversionType, ConvertMapper mapper) { var sourceType = source.GetType(); var assignments = new List <BinaryExpression>(); var sourceParExp = Expression.Parameter(sourceType, "s"); var targetParExp = Expression.Parameter(conversionType, "t"); TypeDescriptorUtility.AddDefaultDynamicProvider(); if (source is IDynamicMetaObjectProvider @dynamic) { GetDynamicMemberAssignments(@dynamic, conversionType, sourceParExp, targetParExp, assignments, mapper); } else { GetGeneralMemberAssignments(source, target, sourceType, conversionType, sourceParExp, targetParExp, assignments, mapper); } var blockExp = Expression.Block(assignments); var funcType = typeof(Action <,>).MakeGenericType(sourceType, conversionType); var lambda = Expression.Lambda(funcType, blockExp, sourceParExp, targetParExp); return(lambda.Compile()); }
/// <summary> /// 初始化对象访问器。 /// </summary> /// <param name="list"></param> private void InitAccessories(IEnumerable <T> list) { var e = list.GetEnumerator(); if (!e.MoveNext()) { return; } hasRows = true; accessories = new Dictionary <string, Func <object, object> >(); propertyTypes = new List <Type>(); if (e.Current is IPropertyFieldMappingResolver resolver) { foreach (var map in resolver.GetDbMapping()) { accessories.Add(map.FieldName, map.ValueFunc); propertyTypes.Add(map.PropertyType); } } else { #if !NET35 TypeDescriptorUtility.AddDefaultDynamicProvider(); #endif foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(e.Current)) { if (property.PropertyType.IsDbTypeSupported()) { accessories.Add(property.Name, o => property.GetValue(o)); propertyTypes.Add(property.PropertyType); } } } }
/// <summary> /// 使用另一个对象对源对象进行扩展,这类似于 jQuery 中的 extend 方法。 /// </summary> /// <param name="source">源对象。</param> /// <param name="other">用于扩展的另一个对象。</param> /// <returns></returns> public static object Extend(this object source, object other) { if (source == null) { return(other); } if (other == null) { return(source); } #if !NET35 TypeDescriptorUtility.AddDefaultDynamicProvider(); var sourceProperties = TypeDescriptor.GetProperties(source); var otherProperties = TypeDescriptor.GetProperties(other); var expando = new ExpandoObject(); var dictionary = (IDictionary <string, object>)expando; var sourceLazy = source as ILazyManager; var otherLazy = other as ILazyManager; foreach (PropertyDescriptor p in sourceProperties) { if (sourceLazy != null && !sourceLazy.IsValueCreated(p.Name)) { continue; } dictionary.Add(p.Name, p.GetValue(source)); } foreach (PropertyDescriptor p in otherProperties) { if (otherLazy != null && !otherLazy.IsValueCreated(p.Name)) { continue; } if (!dictionary.ContainsKey(p.Name)) { dictionary.Add(p.Name, p.GetValue(other)); } } return(expando); #else var sourceType = source.GetType(); var otherType = other.GetType(); var sr = GetObjectReader(sourceType); var or = GetObjectReader(otherType); var sourcePropertyNames = sr.GetCanReadProperties(); var sourceProperties = FilterProperties(sourcePropertyNames, source).Select(s => sourceType.GetProperty(s)); var otherProperties = FilterProperties(or.GetCanReadProperties(), other).Except(sourcePropertyNames).Select(s => otherType.GetProperty(s)); //使用缓存管理,key为两类型名称的组合 var key = sourceType.Name + "$" + otherType.Name; var cacheMgr = MemoryCacheManager.Instance; var instanceType = cacheMgr.TryGet(key, () => BuildNewObjectType(sourceType.Name + "_Ex", sourceProperties.Union(otherProperties))); var values = ReadObjectValues(source, other, sourceProperties, otherProperties); //返回一个新实例对象 return(instanceType.New(values)); #endif }
/// <summary> /// 导出Excel。 /// </summary> /// <param name="templateFileName">模版文件。</param> /// <param name="data">列表数据</param> /// <param name="extendKeyValues">扩展绑定的数据。</param> /// <param name="staticInfo">静态信息</param> /// <param name="password">保护的密码。</param> public static byte[] Export(string templateFileName, IList data, object staticInfo, Dictionary <string, string> extendKeyValues = null, string password = null, Action <ISheet, ExportingDocument> initializer = null) { int count = 0; if (data != null) { count = data.Count; } var fileName = templateFileName.Substring(templateFileName.LastIndexOf("\\") + 1); if (templateFileName.IndexOf(":\\") == -1) { templateFileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, templateFileName); } if (!File.Exists(templateFileName)) { throw new Exception("没有找到对应的 Excel 模板文件。"); } using (var stream = new FileStream(templateFileName, FileMode.Open, FileAccess.Read)) { var workbook = new HSSFWorkbook(stream); var sheet = workbook.GetSheetAt(0); sheet.ForceFormulaRecalculation = true; // 加密文档 if (!string.IsNullOrEmpty(password)) { sheet.ProtectSheet(password); } var document = ParseDocument(sheet); var startRowIndex = document.DataSets[0].StartRowIndex; var source = sheet.GetRow(startRowIndex); if (document.Extend != null && extendKeyValues != null) { var r = document.Extend.RowIndex; var c = document.Extend.ColumnIndex; var index = 0; foreach (var kvp in extendKeyValues) { var cell = document.Extend.Row.GetCell(c + index) ?? document.Extend.Row.CreateCell(c + index); cell.SetCellValue(kvp.Value); cell.CellStyle = document.Extend.CellStyle; cell = source.GetCell(c + index) ?? source.CreateCell(c + index); cell.CellStyle = source.GetCell(c).CellStyle; index++; document.DataSets[0].Properties.Add(cell, new CellDataMap(kvp.Key, $"[{kvp.Key}]")); } } TypeDescriptorUtility.AddDefaultDynamicProvider(); initializer?.Invoke(sheet, document); if (count == 0) { //删除定义字段标签的行 sheet.RemoveRow(source); //上移一行 //sheet.ShiftRows(startRowIndex + 1, sheet.LastRowNum, -1, true, true); } else if (data != null) { //sheet.ShiftRows(startRowIndex + 1, sheet.LastRowNum, count); FillSheet(sheet, data, document, source); } if (staticInfo != null) { foreach (var formula in document.Formulas) { var array = new ArrayList(); if (formula.Parameters != null && formula.Parameters.Count > 0) { var properties = TypeDescriptor.GetProperties(staticInfo); foreach (var par in formula.Parameters) { var property = properties[par]; if (property != null) { var value = property.GetValue(staticInfo); array.Add(value); } else { array.Add(string.Empty); } } } if (array.Count != 0) { SetCellString(formula.Cell, string.Format(formula.Formula, array.ToArray())); } } } using (var mstram = new MemoryStream()) { workbook.Write(mstram); return(mstram.ToArray()); } } }