Пример #1
0
        private void btnAddRelation_Click(Object sender, EventArgs e)
        {
            IDataTable table = GetSelectedTable();

            if (table == null)
            {
                return;
            }

            IDataRelation dr = table.CreateRelation();

            table.Relations.Add(dr);

            dgvRelation.DataSource  = null;
            dgvRelation.DataSource  = table.Relations;
            pgColumn.SelectedObject = dr;
        }
Пример #2
0
        /// <summary>复制数据表到另一个数据表,复制所有数据列、索引和关系</summary>
        /// <param name="src"></param>
        /// <param name="des"></param>
        /// <param name="resetColumnID">是否重置列ID</param>
        /// <returns></returns>
        public static IDataTable CopyAllFrom(this IDataTable src, IDataTable des, Boolean resetColumnID = false)
        {
            src.CopyFrom(des);
            src.Columns.AddRange(des.Columns.Select(i => src.CreateColumn().CopyFrom(i)));
            src.Indexes.AddRange(des.Indexes.Select(i => src.CreateIndex().CopyFrom(i)));
            src.Relations.AddRange(des.Relations.Select(i => src.CreateRelation().CopyFrom(i)));
            // 重载ID
            //if (resetColumnID) src.Columns.ForEach((it, i) => it.ID = i + 1);
            if (resetColumnID)
            {
                for (int i = 0; i < src.Columns.Count; i++)
                {
                    src.Columns[i].ID = i + 1;
                }
            }

            return(src);
        }
Пример #3
0
        /// <summary>猜测表间关系</summary>
        /// <param name="table"></param>
        /// <param name="rtable"></param>
        /// <param name="rname"></param>
        /// <param name="column"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public virtual Boolean GuessRelation(IDataTable table, IDataTable rtable, String rname, IDataColumn column, String name)
        {
            if (name.Length <= rtable.Name.Length || !name.StartsWith(rtable.Name, StringComparison.OrdinalIgnoreCase)) return false;

            var key = name.Substring(rtable.Name.Length);
            var dc = rtable.GetColumn(key);
            // 猜测两表关联关系时,两个字段的类型也必须一致
            if (dc == null || dc.DataType != column.DataType) return false;

            // 建立关系
            var dr = table.CreateRelation();
            dr.Column = column.Name;
            dr.RelationTable = rtable.Name;
            dr.RelationColumn = dc.Name;
            // 表关系这里一般是多对一,比如管理员的RoleID=>Role+Role.ID,对于索引来说,不是唯一的
            dr.Unique = false;
            // 当然,如果这个字段column有唯一索引,那么,这里也是唯一的。这就是典型的一对一
            if (column.PrimaryKey || column.Identity)
                dr.Unique = true;
            else
            {
                var di = table.GetIndex(column.Name);
                if (di != null && di.Unique) dr.Unique = true;
            }

            dr.Computed = true;
            if (table.GetRelation(dr) == null) table.Relations.Add(dr);

            // 给另一方建立关系
            //foreach (IDataRelation item in rtable.Relations)
            //{
            //    if (item.Column == dc.Name && item.RelationTable == table.Name && item.RelationColumn == column.Name) return dr;
            //}
            if (rtable.GetRelation(dc.Name, table.Name, column.Name) != null) return true;

            dr = rtable.CreateRelation();
            dr.Column = dc.Name;
            dr.RelationTable = table.Name;
            dr.RelationColumn = column.Name;
            // 那么这里就是唯一的啦
            dr.Unique = true;
            // 当然,如果字段dc不是主键,也没有唯一索引,那么关系就不是唯一的。这就是典型的多对多
            if (!dc.PrimaryKey && !dc.Identity)
            {
                var di = rtable.GetIndex(dc.Name);
                // 没有索引,或者索引不是唯一的
                if (di == null || !di.Unique) dr.Unique = false;
            }

            dr.Computed = true;
            if (rtable.GetRelation(dr) == null) rtable.Relations.Add(dr);

            return true;
        }
Пример #4
0
        /// <summary>读取</summary>
        /// <param name="table"></param>
        /// <param name="reader"></param>
        /// <returns></returns>
        public static IDataTable ReadXml(this IDataTable table, XmlReader reader)
        {
            // 读属性
            if (reader.HasAttributes)
            {
                reader.MoveToFirstAttribute();
                ReadXml(reader, table);
            }

            reader.ReadStartElement();

            // 读字段
            reader.MoveToElement();
            // 有些数据表模型没有字段
            if (reader.NodeType == XmlNodeType.Element && reader.Name.EqualIgnoreCase("Table"))
            {
                return(table);
            }

            while (reader.NodeType != XmlNodeType.EndElement)
            //while (reader.NodeType == XmlNodeType.Element)
            {
                switch (reader.Name)
                {
                case "Columns":
                    reader.ReadStartElement();
                    var id = 1;
                    while (reader.IsStartElement())
                    {
                        var dc = table.CreateColumn();
                        dc.ID = id++;
                        var v = reader.GetAttribute("DataType");
                        if (v != null)
                        {
                            dc.DataType = v.GetTypeEx();
                            v           = reader.GetAttribute("Length");
                            var len = 0;
                            if (v != null && Int32.TryParse(v, out len))
                            {
                                dc.Length = len;
                            }

                            // 含有ID表示是旧的,不需要特殊处理,否则一些默认值会不对
                            v = reader.GetAttribute("ID");
                            if (v == null)
                            {
                                dc = Fix(dc, dc);
                            }
                        }
                        (dc as IXmlSerializable).ReadXml(reader);
                        table.Columns.Add(dc);
                    }
                    reader.ReadEndElement();

                    // 修正可能的主字段
                    if (!table.Columns.Any(e => e.Master))
                    {
                        var f = table.Columns.FirstOrDefault(e => e.Name.EqualIgnoreCase("Name", "Title"));
                        if (f != null)
                        {
                            f.Master = true;
                        }
                    }
                    break;

                case "Indexes":
                    reader.ReadStartElement();
                    while (reader.IsStartElement())
                    {
                        var di = table.CreateIndex();
                        (di as IXmlSerializable).ReadXml(reader);
                        di.Fix();
                        table.Indexes.Add(di);
                    }
                    reader.ReadEndElement();
                    break;

                case "Relations":
                    reader.ReadStartElement();
                    while (reader.IsStartElement())
                    {
                        var dr = table.CreateRelation();
                        (dr as IXmlSerializable).ReadXml(reader);
                        if (table.GetRelation(dr) == null)
                        {
                            table.Relations.Add(dr);
                        }
                    }
                    reader.ReadEndElement();
                    break;

                default:
                    // 这里必须处理,否则加载特殊Xml文件时将会导致死循环
                    reader.Read();
                    break;
                }
            }

            //if (reader.NodeType != XmlNodeType.Element && reader.NodeType != XmlNodeType.EndElement) reader.Read();
            //reader.ReadEndElement();
            if (reader.NodeType == XmlNodeType.EndElement)
            {
                reader.ReadEndElement();
            }

            return(table);
        }
Пример #5
0
        /// <summary>猜测表间关系</summary>
        /// <param name="table"></param>
        /// <param name="rtable"></param>
        /// <param name="rname"></param>
        /// <param name="column"></param>
        /// <param name="name">名称</param>
        /// <returns></returns>
        public virtual Boolean GuessRelation(IDataTable table, IDataTable rtable, String rname, IDataColumn column, String name)
        {
            if (table == null || rtable == null || rname == null || column == null || name == null)
            {
                return(false);
            }
            if (name.Length <= rtable.TableName.Length || !name.StartsWithIgnoreCase(rtable.TableName))
            {
                return(false);
            }

            var key = name.Substring(rtable.TableName.Length);
            var dc  = rtable.GetColumn(key);

            // 猜测两表关联关系时,两个字段的类型也必须一致
            if (dc == null || dc.DataType != column.DataType)
            {
                return(false);
            }

            // 建立关系
            var dr = table.CreateRelation();

            dr.Column         = column.ColumnName;
            dr.RelationTable  = rtable.TableName;
            dr.RelationColumn = dc.ColumnName;
            // 表关系这里一般是多对一,比如管理员的RoleID=>Role+Role.ID,对于索引来说,不是唯一的
            dr.Unique = false;
            // 当然,如果这个字段column有唯一索引,那么,这里也是唯一的。这就是典型的一对一
            if (column.PrimaryKey || column.Identity)
            {
                dr.Unique = true;
            }
            else
            {
                var di = table.GetIndex(column.ColumnName);
                if (di != null && di.Unique)
                {
                    dr.Unique = true;
                }
            }

            dr.Computed = true;
            if (table.GetRelation(dr) == null)
            {
                table.Relations.Add(dr);
            }

            // 给另一方建立关系
            if (rtable.GetRelation(dc.ColumnName, table.TableName, column.ColumnName) != null)
            {
                return(true);
            }

            dr                = rtable.CreateRelation();
            dr.Column         = dc.ColumnName;
            dr.RelationTable  = table.TableName;
            dr.RelationColumn = column.ColumnName;
            // 那么这里就是唯一的啦
            dr.Unique = true;
            // 当然,如果字段dc不是主键,也没有唯一索引,那么关系就不是唯一的。这就是典型的多对多
            if (!dc.PrimaryKey && !dc.Identity)
            {
                var di = rtable.GetIndex(dc.ColumnName);
                // 没有索引,或者索引不是唯一的
                if (di == null || !di.Unique)
                {
                    dr.Unique = false;
                }
            }

            dr.Computed = true;
            if (rtable.GetRelation(dr) == null)
            {
                rtable.Relations.Add(dr);
            }

            return(true);
        }
Пример #6
0
        /// <summary>读取</summary>
        /// <param name="table"></param>
        /// <param name="reader"></param>
        /// <returns></returns>
        public static IDataTable ReadXml(this IDataTable table, XmlReader reader)
        {
            // 读属性
            if (reader.HasAttributes)
            {
                reader.MoveToFirstAttribute();
                //do
                //{
                //    switch (reader.Name)
                //    {
                //        case "ID":
                //            table.ID = reader.ReadContentAsInt();
                //            break;
                //        case "Name":
                //            table.Name = reader.ReadContentAsString();
                //            break;
                //        case "Alias":
                //            table.Alias = reader.ReadContentAsString();
                //            break;
                //        case "Owner":
                //            table.Owner = reader.ReadContentAsString();
                //            break;
                //        case "DbType":
                //            table.DbType = (DatabaseType)Enum.Parse(typeof(DatabaseType), reader.ReadContentAsString());
                //            break;
                //        case "IsView":
                //            table.IsView = Boolean.Parse(reader.ReadContentAsString());
                //            break;
                //        case "Description":
                //            table.Description = reader.ReadContentAsString();
                //            break;
                //        default:
                //            break;
                //    }
                //} while (reader.MoveToNextAttribute());
                ReadXml(reader, table);
            }

            reader.ReadStartElement();

            // 读字段
            reader.MoveToElement();
            while (reader.NodeType != XmlNodeType.EndElement)
            {
                switch (reader.Name)
                {
                case "Columns":
                    reader.ReadStartElement();
                    while (reader.IsStartElement())
                    {
                        var dc = table.CreateColumn();
                        (dc as IXmlSerializable).ReadXml(reader);
                        table.Columns.Add(dc);
                    }
                    reader.ReadEndElement();
                    break;

                case "Indexes":
                    reader.ReadStartElement();
                    while (reader.IsStartElement())
                    {
                        var di = table.CreateIndex();
                        (di as IXmlSerializable).ReadXml(reader);
                        table.Indexes.Add(di);
                    }
                    reader.ReadEndElement();
                    break;

                case "Relations":
                    reader.ReadStartElement();
                    while (reader.IsStartElement())
                    {
                        var dr = table.CreateRelation();
                        (dr as IXmlSerializable).ReadXml(reader);
                        if (table.GetRelation(dr) == null)
                        {
                            table.Relations.Add(dr);
                        }
                    }
                    reader.ReadEndElement();
                    break;

                default:
                    break;
                }
            }

            //reader.ReadEndElement();
            if (reader.NodeType == XmlNodeType.EndElement)
            {
                reader.ReadEndElement();
            }

            return(table);
        }