/// <summary> /// 利用DbColumn的信息,去除匹配到相同列的多余属性,只选择其中一个。选择的规定为: /// 1、当只有一个属性匹配时,则选择之; /// 2、当有多个属性匹配,则深度不同时,选择深度最小者。 /// 如A.B.C.D, A.B.D。则选择后者 /// 3、如果有多个属性匹配,且最小深度有多个,则默认选择第一个。 /// </summary> /// <returns></returns> private IList <DBColumnMapping> DeduplicateDbColumnMappingByOffset(IList <LeafPropertyNode> leafs) { var filtered = new List <DBColumnMapping>(); foreach (var group in leafs .SelectMany(l => l.DbColumnMappings) .GroupBy(m => m.DestColumnOffset)) { //规则一 if (group.Count() == 1) { filtered.Add(group.First()); } else { //规则二、三 DBColumnMapping selected = group.OrderBy(t => t.Host.Depth * 10 + (int)t.Option).First(); filtered.Add(selected); foreach (var mapping in group) { if (!object.ReferenceEquals(mapping, selected)) { m_classLogger.WarnFormat("Column mapping {0} on {1} abandoned as its offset {2} is already used by {3}", mapping, mapping.Host, mapping.DestColumnOffset, selected); } } } } return(filtered); }
public int GetColumnOffset(string name) { DBColumnMapping columnAttr = m_dbColumnMappings.FirstOrDefault( col => string.Equals(col.DestColumnName, name, StringComparison.OrdinalIgnoreCase)); return(columnAttr == null ? -1 : columnAttr.DestColumnOffset); }
private void AutoCreateDBColumnMapping(IList <LeafPropertyNode> leafNodes) { //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 has no attribute on each of its properties.", typeof(T)); #region 没有属性存在DbColumnMapping。因此,采用属性名称匹配数据库 DataTable dataTable = this.SchemaTable; foreach (DataColumn column in dataTable.Columns) { if (column == null || column.ReadOnly) { continue; } IEnumerable <LeafPropertyNode> matchedLeafs = leafNodes.Where( t => string.Equals(t.PropertyInfo.Name, column.ColumnName, StringComparison.OrdinalIgnoreCase)); foreach (LeafPropertyNode leaf in matchedLeafs) { var dbMapping = new DBColumnMapping(this.m_destLabel, column.Ordinal, null) { DestColumnName = column.ColumnName }; dbMapping.Host = leaf; leaf.DbColumnMappings.Add(dbMapping); } } #endregion }
public InvalidDBColumnMappingException(string description, DBColumnMapping mapping, LeafPropertyNode node) : base() { this.m_description = description; this.m_mapping = mapping; this.m_node = node; }
/// <summary> /// Register an external mapping to affect the column mapping process by type accessors. /// </summary> /// <typeparam name="T">Type of the root object</typeparam> /// <typeparam name="TValue">Return type of the leaf property</typeparam> /// <param name="propertyPath">A lambda expression which defines the property path from root type to the leaf property</param> /// <param name="mapping">The mapping to register to the give property path</param> public static void RegisterMapping <T, TValue>(Expression <Func <T, TValue> > propertyPath, DBColumnMapping mapping) where T : class { //todo: add lambda expression check RegisterMapping(propertyPath.Body, mapping); }
public string GetName(int columnOffset) { DBColumnMapping columnAttr = m_dbColumnMappings.FirstOrDefault(col => col.DestColumnOffset == columnOffset); return(columnAttr == null ? null : columnAttr.DestColumnName); }
private static void RegisterMapping(Expression propertyPath, DBColumnMapping mapping) { s_externalMappings.Add(Tuple.Create(propertyPath, mapping)); }
/// <summary> /// 说明:此方法用于利用数据库表的列字段的:位置或名称,将DbColumnMapping补全。 /// 如果输入的propertyInfo.PropertyType不是“原子类型”或“String”,显然在数据库中不会有匹配的列;所以直接返回 /// </summary> /// <param name="propertyInfo"></param> /// <param name="mapping"></param> private void PopulateDbColumnMapping(LeafPropertyNode leaf, DBColumnMapping mapping) { DataTable schemaTable = this.SchemaTable; if (mapping.IsDestColumnNameOk() && mapping.IsDestColumnOffsetOk()) { DataColumn col = schemaTable.Columns[mapping.DestColumnOffset]; if (col == null) { if (mapping.Option == ColumnMappingOption.Optional) { m_classLogger.DebugFormat("Optional column mapping ignored for table {0}: {1}", m_destinationTablename, mapping); mapping.DestColumnOffset = -1; return; } else { var desc = string.Format( "can not find column with offset {0} in table {1} ", mapping.DestColumnOffset, m_destinationTablename); throw new InvalidDBColumnMappingException(desc, mapping, leaf); } } if (col.ColumnName != mapping.DestColumnName) { var desc = string.Format( "Column name from db {0} is inconsistent with that in db mapping {1} ", col.ColumnName, mapping); throw new InvalidDBColumnMappingException(desc, mapping, leaf); } return; } //说明当前的mapping的列名称出错(null),而位置参数正确。则读取数据库表获得要相应的列名称 if (!mapping.IsDestColumnNameOk() && mapping.IsDestColumnOffsetOk()) { DataColumn col = schemaTable.Columns[mapping.DestColumnOffset]; if (col == null) { if (mapping.Option == ColumnMappingOption.Optional) { m_classLogger.DebugFormat("Optional column mapping ignored for table {0}: {1}", m_destinationTablename, mapping); mapping.DestColumnOffset = -1; return; } else { var desc = string.Format( "can not find column with offset {0} in table {1} ", mapping.DestColumnOffset, m_destinationTablename); throw new InvalidDBColumnMappingException(desc, mapping, leaf); } } mapping.DestColumnName = col.ColumnName; this.m_classLogger.DebugFormat("Populated column name for DBColumnMapping: {0} on property node: {1} by table {2}", mapping, leaf, m_destinationTablename); return; } //说明当前的mapping的列名称存在,而位置参数出错(-1)。则读取数据库表获得相应的列位置参数 if (mapping.IsDestColumnNameOk() && !mapping.IsDestColumnOffsetOk()) { DataColumn col = schemaTable.Columns[mapping.DestColumnName]; if (col == null) { if (mapping.Option == ColumnMappingOption.Optional) { m_classLogger.DebugFormat( "Optional column mapping ignored for table {0}: {1}", m_destinationTablename, mapping); mapping.DestColumnOffset = -1; return; } else { var desc = string.Format( "can not find column with name {0} in table {1} ", mapping.DestColumnName, m_destinationTablename); throw new InvalidDBColumnMappingException(desc, mapping, leaf); } } mapping.DestColumnOffset = col.Ordinal; this.m_classLogger.DebugFormat("Populated column offset for DBColumnMapping: {0} on property node: {1} by table {2}", mapping, leaf, m_destinationTablename); return; } //说明当前的mapping列名称不存在,位置参数也不存在,因此,根据PropertyInfo.Name读取数据库 DataColumn guessColumn = schemaTable.Columns[leaf.PropertyInfo.Name]; if (guessColumn == null) { if (mapping.Option == ColumnMappingOption.Optional) { m_classLogger.DebugFormat("Optional column mapping ignored for table {0}: {1}", m_destinationTablename, mapping); mapping.DestColumnOffset = -1; return; } else { var desc = string.Format( "can not find column with property name {0} in table {1} ", leaf.PropertyInfo.Name, m_destinationTablename); throw new InvalidDBColumnMappingException(desc, mapping, leaf); } } mapping.DestColumnOffset = guessColumn.Ordinal; mapping.DestColumnName = guessColumn.ColumnName; this.m_classLogger.DebugFormat("Populated column name and offset for DBColumnMapping: {0} on property node: {1} by table {2}", mapping, leaf, m_destinationTablename); }