public ValueTypeMapping(PropertyInfo currentPropertyInfo, int parentKey, int depth, DBColumnMapping dbColumnMapping = null) { CurrentPropertyInfo = currentPropertyInfo; ParentKey = parentKey; Depth = depth; DbColumnMapping = dbColumnMapping; }
public int GetColumnOffset(string name) { DBColumnMapping columnAttr = m_dbColumnMappings.FirstOrDefault( col => string.Equals(col.DestColumnName, name, StringComparison.OrdinalIgnoreCase)); return(columnAttr == null ? -1 : columnAttr.DestColumnOffset); }
/// <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); }
public string GetName(int columnOffset) { DBColumnMapping columnAttr = m_dbColumnMappings.FirstOrDefault(col => col.DestColumnOffset == columnOffset); return(columnAttr == null ? null : columnAttr.DestColumnName); }
/// <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; }
/// <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); }