表合并

    public class DataTableJoiner
    {
        #region Variables
        private LibDataTable left;
        private List<Joiner> _joiners = new List<Joiner>();
        #endregion

        #region Constructor
        public DataTableJoiner(LibDataTable left)
        {
            Left = left;
        }
        #endregion

        #region Property
        public LibDataTable Left
        {
            get { return left; }
            set { left = value; }
        }

        public List<Joiner> Joiners
        {
            get { return _joiners; }
            set { _joiners = value; }
        }
        #endregion

        #region Public Method
        public LibDataTable Execute()
        {
            foreach (Joiner joiner in _joiners)
            {
                switch (joiner.JoinType)
                {
                    case JoinType.Left:
                        LeftJoin(joiner);
                        break;
                    case JoinType.Inner:
                        InnerJoin(joiner);
                        break;
                    case JoinType.Full:
                        FullJoin(joiner);
                        break;
                }
            }

            return left;
        }


        public LibDataTable Join()
        {
            return Execute();
        }
        #endregion

        #region Private Metod
        /// <summary>
        /// 内连接,实现SQL中的inner join
        /// </summary>
        /// <returns></returns>
        private void InnerJoin(Joiner joiner)
        {
            LibDataTable result = MergeColumns(joiner.Right);

            foreach (DataRow leftRow in Left.Rows)
            {
                DataRow[] rightRows = joiner.Right.Select(joiner.On(leftRow));

                foreach (DataRow rightRow in rightRows)
                {
                    DataRow mergedRow = result.NewRow();

                    CopyRow(leftRow, mergedRow);
                    CopyRow(rightRow, mergedRow);

                    result.Rows.Add(mergedRow);
                    result.AcceptChanges();
                }
            }

            left = result;
        }

        /// <summary>
        /// 左连接,实现SQL中的inner join
        /// </summary>
        /// <returns></returns>
        private void LeftJoin(Joiner joiner)
        {
            LibDataTable result = MergeColumns(joiner.Right);

            foreach (DataRow leftRow in Left.Rows)
            {
                DataRow[] rightRows = joiner.Right.Select(joiner.On(leftRow));


                if (rightRows.Length == 0)
                {
                    DataRow mergedRow = result.NewRow();
                    CopyRow(leftRow, mergedRow);
                    result.Rows.Add(mergedRow);
                    result.AcceptChanges();
                }
                else
                {
                    foreach (DataRow rightRow in rightRows)
                    {
                        DataRow mergedRow = result.NewRow();

                        CopyRow(leftRow, mergedRow);
                        CopyRow(rightRow, mergedRow);

                        result.Rows.Add(mergedRow);
                        result.AcceptChanges();
                    }
                }
            }

            left = result;
        }

        /// <summary>
        /// 全连接,实现SQL中的inner join
        /// </summary>
        /// <returns></returns>
        private void FullJoin(Joiner joiner)
        {
            try
            {

                LibDataTable result = MergeColumns(joiner.Right);
                List<DataRow> mergedRows = new List<DataRow>();


                foreach (DataRow leftRow in Left.Rows)
                {
                    DataRow[] rightRows = joiner.Right.Select(joiner.On(leftRow));

                    if (rightRows.Length == 0)
                    {
                        DataRow mergedRow = result.NewRow();
                        CopyRow(leftRow, mergedRow);
                        result.Rows.Add(mergedRow);
                        result.AcceptChanges();
                    }
                    else
                    {
                        foreach (DataRow rightRow in rightRows)
                        {
                            DataRow mergedRow = result.NewRow();

                            CopyRow(leftRow, mergedRow);
                            CopyRow(rightRow, mergedRow);

                            result.Rows.Add(mergedRow);
                            result.AcceptChanges();
                        }
                        mergedRows.AddRange(rightRows);
                    }
                }

                foreach (DataRow rigtRow in joiner.Right.Rows)
                {
                    if (mergedRows.Contains(rigtRow)) continue;

                    DataRow mergedRow = result.NewRow();
                    CopyRow(rigtRow, mergedRow);
                    result.Rows.Add(mergedRow);
                    result.AcceptChanges();
                }

                left = result;
            }
            catch (Exception ex)
            {
                throw new Exception(String.Format("Talbe:{0},Message:{1}", joiner.Right.TableName, ex.Message), ex);
            }
        }

        private static void CopyRow(DataRow sourceRow, DataRow targetRow)
        {
            foreach (DataColumn column in targetRow.Table.Columns)
            {
                if (sourceRow.Table.Columns.IndexOf(column.ColumnName) < 0) continue;
                targetRow[column.ColumnName] = sourceRow[column.ColumnName];
            }
        }

        /// <summary>
        /// 创建具有left和join指定列的LibDataTable
        /// </summary>
        /// <returns></returns>
        private LibDataTable MergeColumns(LibDataTable right)
        {
            LibDataTable result = new LibDataTable(left.TableName);

            foreach (DataColumn column in Left.Columns)
            {
                DataColumn col = new DataColumn(column.ColumnName, column.DataType);
                if (IsNumType(column))
                {
                    col.DefaultValue = 0;
                }
                result.Columns.Add(col);
            }

            foreach (DataColumn column in right.Columns)
            {
                if (result.Columns[column.ColumnName] != null) continue;
                DataColumn col = new DataColumn(column.ColumnName, column.DataType);
                if (IsNumType(column))
                {
                    col.DefaultValue = 0;
                }
                result.Columns.Add(col);
            }

            return result;
        }

        private static bool IsNumType(DataColumn column)
        {
            return column.DataType == typeof(Int32)
                    || column.DataType == typeof(Decimal)
                     || column.DataType == typeof(Int16)
                      || column.DataType == typeof(Int64)
                       || column.DataType == typeof(Single)
                       || column.DataType == typeof(Double)
                       || column.DataType == typeof(Byte)

                ;
        }
        #endregion

        #region Public Static Method
        public static LibDataTable LeftJoin(Joiner.JoinDelegate joinDelegate, LibDataTable left, params LibDataTable[] joinTBs)
        {
            return Join(JoinType.Left, joinDelegate, left, joinTBs);
        }

        public static LibDataTable InnerJoin(Joiner.JoinDelegate joinDelegate, LibDataTable left, params LibDataTable[] joinTBs)
        {
            return Join(JoinType.Inner, joinDelegate, left, joinTBs);

        }

        public static LibDataTable FullJoin(Joiner.JoinDelegate joinDelegate, LibDataTable left, params LibDataTable[] joinTBs)
        {
            return Join(JoinType.Full, joinDelegate, left, joinTBs);
        }

        public static LibDataTable Join(JoinType joinType, Joiner.JoinDelegate joinDelegate, LibDataTable left, params LibDataTable[] joinTBs)
        {
            DataTableJoiner tableJoiner = new DataTableJoiner(left);
            foreach (LibDataTable rightTb in joinTBs)
            {
                tableJoiner.Joiners.Add(new Joiner(joinType, rightTb, joinDelegate));
            }

            return tableJoiner.Execute();
        }
        #endregion
    }

    public class Joiner
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="leftRow"></param>
        /// <example>
        /// <code>
        /// Joiner.JoinDelegate joinDelegate = delegate(DataRow leftRow) {return String.Format("Opara={0}",leftRow["Opara"]); };
        /// </code>
        /// </example>
        /// <returns></returns>
        public delegate string JoinDelegate(DataRow leftRow);

        private LibDataTable _right;

        private JoinType _joinType;

        private JoinDelegate _on;

        public Joiner(JoinType joinType, LibDataTable right, JoinDelegate on)
        {
            On = on;
            Right = right;
            JoinType = joinType;
        }

        public JoinDelegate On
        {
            get { return _on; }
            set { _on = value; }
        }

        public LibDataTable Right
        {
            get { return _right; }
            set { _right = value; }
        }

        public JoinType JoinType
        {
            get { return _joinType; }
            set { _joinType = value; }
        }


    }

    public enum JoinType
    {
        Left,
        Inner,
        Full
    }


eg:

  public LibDataTable mergeDataTable(LibDataTable left, LibDataTable right, string checkColumn)
        {
            LibDataTable result = DataTableJoiner.FullJoin(delegate(DataRow leftRow) { return String.Format(checkColumn + "='{0}'", leftRow[checkColumn]); }, left, right);
            return result;
        }

猜你喜欢

转载自blog.csdn.net/fuweiping/article/details/42175093