Пример #1
0
        /// <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);
        }
Пример #2
0
        /// <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);
        }
Пример #3
0
        /// <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);
        }
Пример #4
0
        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);
        }
Пример #5
0
        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());
        }
Пример #6
0
        /// <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));
                    }
                }
            }
        }
Пример #7
0
        /// <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);
        }
Пример #8
0
        /// <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);
            }
        }
Пример #9
0
        /// <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
            }
        }
Пример #10
0
        /// <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);
                }
            }
        }
Пример #11
0
        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);
        }
Пример #12
0
        /// <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);
        }
Пример #13
0
        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);
        }
Пример #14
0
        /// <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);
        }
Пример #15
0
        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());
        }
Пример #16
0
        /// <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);
                    }
                }
            }
        }
Пример #17
0
        /// <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
        }
Пример #18
0
        /// <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());
                }
            }
        }