Пример #1
0
        /// <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);
        }
Пример #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);
        }
Пример #3
0
        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;
 }
Пример #5
0
 /// <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);
 }
Пример #6
0
        public string GetName(int columnOffset)
        {
            DBColumnMapping columnAttr = m_dbColumnMappings.FirstOrDefault(col => col.DestColumnOffset == columnOffset);

            return(columnAttr == null ? null : columnAttr.DestColumnName);
        }
Пример #7
0
 private static void RegisterMapping(Expression propertyPath, DBColumnMapping mapping)
 {
     s_externalMappings.Add(Tuple.Create(propertyPath, mapping));
 }
Пример #8
0
        /// <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);
        }