Esempio n. 1
0
 public ValueTypeMapping(PropertyInfo currentPropertyInfo, int parentKey, int depth,
                         DBColumnMapping dbColumnMapping = null)
 {
     CurrentPropertyInfo = currentPropertyInfo;
     ParentKey           = parentKey;
     Depth           = depth;
     DbColumnMapping = dbColumnMapping;
 }
Esempio n. 2
0
        public int GetColumnOffset(string name)
        {
            DBColumnMapping columnAttr =
                m_dbColumnMappings.FirstOrDefault(
                    col => string.Equals(col.DestColumnName, name, StringComparison.OrdinalIgnoreCase));

            return(columnAttr == null ? -1 : columnAttr.DestColumnOffset);
        }
Esempio n. 3
0
        /// <summary>
        /// Constructs a DbDataJoiner instance
        /// </summary>
        /// <param name="joinOn">Property path from the root object down to the lookup key</param>
        /// <param name="dimTableTarget">Table information of the remote dimension table</param>
        /// <param name="option">Option to use for this dataflow</param>
        /// <param name="batchSize">The batch size for a batched remote look up</param>
        /// <param name="cacheSize">The local cache item count (part of the remote table)</param>
        public DbDataJoiner(Expression <Func <TIn, TLookupKey> > joinOn, TargetTable dimTableTarget, DataflowOptions option, int batchSize = 8 * 1024, int cacheSize = 1024 * 1024)
            : base(option)
        {
            m_dimTableTarget  = dimTableTarget;
            m_batchSize       = batchSize;
            m_batcher         = new BatchBlock <TIn>(batchSize, option.ToGroupingBlockOption()).ToDataflow(option);
            m_batcher.Name    = "Batcher";
            m_lookupNode      = new TransformManyDataflow <JoinBatch <TIn>, TIn>(this.JoinBatch, option);
            m_lookupNode.Name = "LookupNode";
            m_typeAccessor    = TypeAccessorManager <TIn> .GetAccessorForTable(dimTableTarget);

            m_keyComparer = typeof(TLookupKey) == typeof(byte[])
                                    ? (IEqualityComparer <TLookupKey>)((object)new ByteArrayEqualityComparer())
                                    : EqualityComparer <TLookupKey> .Default;
            m_rowCache = new RowCache <TLookupKey>(cacheSize, m_keyComparer);
            m_logger   = Utils.GetNamespaceLogger();

            m_joinOnMapping = m_typeAccessor.DbColumnMappings.First(m => m.Host.PropertyInfo == this.ExtractPropertyInfo(joinOn));

            var transformer =
                new TransformBlock <TIn[], JoinBatch <TIn> >(
                    array => new JoinBatch <TIn>(array, CacheLookupStrategy.RemoteLookup), option.ToExecutionBlockOption()).ToDataflow(option);

            transformer.Name = "ArrayToJoinBatchConverter";

            m_batcher.LinkTo(transformer);
            transformer.LinkTo(m_lookupNode);

            RegisterChild(m_batcher);
            RegisterChild(transformer);
            RegisterChild(m_lookupNode);

            m_dimInserter = new DimTableInserter(this, dimTableTarget, joinOn, option)
            {
                Name = "DimInserter"
            };
            var hb = new HeartbeatNode <JoinBatch <TIn> >(option);

            m_dimInserter.RegisterDependency(m_lookupNode);

            m_dimInserter.LinkTo(hb);
            hb.LinkTo(m_lookupNode);

            RegisterChild(m_dimInserter);
            RegisterChild(hb);
            RegisterChildRing(transformer.CompletionTask, m_lookupNode, m_dimInserter, hb);
        }
Esempio n. 4
0
        public string GetName(int columnOffset)
        {
            DBColumnMapping columnAttr = m_dbColumnMappings.FirstOrDefault(col => col.DestColumnOffset == columnOffset);

            return(columnAttr == null ? null : columnAttr.DestColumnName);
        }
Esempio n. 5
0
        /// <summary>
        ///     说明:此方法用于利用数据库表的列字段的:位置或名称,将DbColumnMapping补全。
        ///     如果输入的propertyInfo.PropertyType不是“原子类型”或“String”,显然在数据库中不会有匹配的列;所以直接返回
        /// </summary>
        /// <param name="propertyInfo"></param>
        /// <param name="mapping"></param>
        private void FormatDbColumnMapping(PropertyInfo propertyInfo, ref DBColumnMapping mapping)
        {
            Type type = propertyInfo.PropertyType;
            bool tag  = propertyInfo.PropertyType.IsValueType || propertyInfo.PropertyType == typeof(string);

            if (tag == false)
            {
                return;
            }

            if (mapping.IsDestColumnNameOk() && mapping.IsDestColumnOffsetOk())
            {
                return;
            }

            DataTable schemaTable = GetSchemaTable();

            //说明当前的mapping的列名称出错(null),而位置参数正确。则读取数据库表获得要相应的列名称
            if (mapping.IsDestColumnNameOk() == false && mapping.IsDestColumnOffsetOk())
            {
                DataColumn col = schemaTable.Columns[mapping.DestColumnOffset];
                if (col == null)
                {
                    LogHelper.Logger.WarnFormat(
                        "can not find column with column offset:{0} with property name:{1} in table: {2}, currnet db mapping:{3}",
                        mapping.DestColumnOffset, propertyInfo.Name, m_destinationTablename, mapping);
                    return;
                }
                mapping.DestColumnName = col.ColumnName;
                return;
            }

            //说明当前的mapping的列名称存在,而位置参数出错(-1)。则读取数据库表获得相应的列位置参数
            if (mapping.IsDestColumnNameOk() && mapping.IsDestColumnOffsetOk() == false)
            {
                DataColumn col = schemaTable.Columns[mapping.DestColumnName];
                if (col == null)
                {
                    LogHelper.Logger.WarnFormat(
                        "can not find column with column name:{0} with property name:{1} in table:{2}, current db mapping:{3}",
                        mapping.DestColumnName, propertyInfo.Name, m_destinationTablename, mapping);
                    return;
                }

                mapping.DestColumnOffset = col.Ordinal;
                return;
            }

            //说明当前的mapping列名称不存在,位置参数也不存在,因此,根据PropertyInfo.Name读取数据库
            DataColumn col2 = schemaTable.Columns[propertyInfo.Name];

            if (col2 == null)
            {
                LogHelper.Logger.WarnFormat(
                    "can not find column with property name:{0} in table:{1}, current db mapping:{2}", propertyInfo.Name,
                    m_destinationTablename, mapping);
                return;
            }
            mapping.DestColumnOffset = col2.Ordinal;
            mapping.DestColumnName   = col2.ColumnName;
        }
Esempio n. 6
0
        /// <summary>
        ///     对所有的值类型与stirng类型进行“格式化”,并生成相应的属性到Column的映射关系。
        ///     在此:只是简单的将属性映射到Column,不考虑两者多对多的关系的判断。
        /// </summary>
        /// <param name="valueTypeMappings"></param>
        /// <param name="hasMapping"></param>
        /// <returns></returns>
        private IList <ValueTypeMapping> SelectedValueProperties(IList <ValueTypeMapping> valueTypeMappings,
                                                                 bool hasMapping)
        {
            var rightTypeMappings = new List <ValueTypeMapping>();


            if (hasMapping)
            {
                #region  属性存在DbColumnMapping

                foreach (ValueTypeMapping valueTypeMapping in valueTypeMappings)
                {
                    #region format DBColumnMappings

                    var attrs =
                        (DBColumnMapping[])
                        valueTypeMapping.CurrentPropertyInfo.GetCustomAttributes(typeof(DBColumnMapping), true);

                    DBColumnMapping[] destAttrs = attrs.Where(attr => attr.DestLabel == m_destLabel).ToArray();

                    DBColumnMapping[] selectedAttrs =
                        destAttrs.Where(attr => attr.IsTableNameMatch(m_destinationTablename)).ToArray();

                    //说明:如果已经有满足数据库表匹配的Attribute存在,则选择这些Attribute;
                    //否则,选择数据库表名称为默认值(即null)的Attribute。
                    selectedAttrs = selectedAttrs.Length != 0
                        ? selectedAttrs
                        : destAttrs.Where(attr => attr.IsDefaultDestTableName()).ToArray();

                    if (selectedAttrs.Length == 0)
                    {
                        continue;
                    }

                    for (int i = 0; i < selectedAttrs.Length; ++i)
                    {
                        LogHelper.Logger.TraceFormat("starting format DBColumnMapping: {0} for property: {1}",
                                                     selectedAttrs[i], valueTypeMapping.CurrentPropertyInfo);
                        FormatDbColumnMapping(valueTypeMapping.CurrentPropertyInfo, ref selectedAttrs[i]);
                        LogHelper.Logger.TraceFormat("ending format DBColumnMapping:{0} for property:{1}",
                                                     selectedAttrs[i], valueTypeMapping.CurrentPropertyInfo);
                        if (selectedAttrs[i].IsDestColumnOffsetOk() == false ||
                            selectedAttrs[i].IsDestColumnNameOk() == false)
                        {
                            LogHelper.Logger.WarnFormat(
                                "failed to format DBColumnMapping:{0} for prop:{1}. check whether its Attribute is mapping to database table correctly. and it's not added to mapping table.",
                                selectedAttrs[i], valueTypeMapping.CurrentPropertyInfo);
                        }
                    }

                    #endregion

                    DBColumnMapping[] rightAttrs =
                        selectedAttrs.Where(attr => attr.IsDestColumnOffsetOk() && attr.IsDestColumnNameOk()).ToArray();
                    if (rightAttrs.Length == 0)
                    {
                        LogHelper.Logger.WarnFormat("mapping to column failed for property:{0}",
                                                    valueTypeMapping.CurrentPropertyInfo);
                        continue;
                    }


                    foreach (DBColumnMapping rightAttr in rightAttrs)
                    {
                        rightTypeMappings.Add(new ValueTypeMapping(valueTypeMapping.CurrentPropertyInfo,
                                                                   valueTypeMapping.ParentKey, valueTypeMapping.Depth, rightAttr));
                    }
                }

                #endregion

                return(rightTypeMappings);
            }

            //there isn't property with DestLabel attribute,so we can get it from database table.
            LogHelper.Logger.WarnFormat(
                "mapping property by schema table for current type: {0}, which do not have attribute on all properties.",
                typeof(T));

            #region 没有属性存在DbColumnMapping。因此,采用属性名称匹配数据库

            DataTable dataTable = GetSchemaTable();

            foreach (DataColumn column in dataTable.Columns)
            {
                if (column == null || column.ReadOnly)
                {
                    continue;
                }

                IEnumerable <ValueTypeMapping> tempMappings =
                    valueTypeMappings.Where(
                        t =>
                        string.Equals(t.CurrentPropertyInfo.Name, column.ColumnName,
                                      StringComparison.OrdinalIgnoreCase));
                ValueTypeMapping[] typeMappings = tempMappings as ValueTypeMapping[] ?? tempMappings.ToArray();
                foreach (ValueTypeMapping typeMapping in typeMappings)
                {
                    var dbMapping = new DBColumnMapping(m_destLabel, column.Ordinal, null, m_destinationTablename)
                    {
                        DestColumnName = column.ColumnName
                    };
                    typeMapping.DbColumnMapping = dbMapping;
                    rightTypeMappings.Add(typeMapping);
                }
            }

            #endregion

            return(rightTypeMappings);
        }