首页 > 代码库 > 层次关系表格,不用递归,快速检索。HierarchyId

层次关系表格,不用递归,快速检索。HierarchyId

       最近这几天写了个T4自动实现EF code first和Ado的存储过程。使用过程中发现了一个Sql的类型为HierarchyId。看到时真是百思不得齐姐。算了查一下MSDN吧。从微软官网找到了HierarchyId类型。悲催了。这个字段没有对应C# CLR类型。使用EF6时报错,提示我应该是用Byte[]类型,执行一遍程序。还是有错误,算了谷歌吧。谷歌了一下,发现有解决方案了,什么HierarchyId而且不是SQLTypes的HierarchyId,哦 EF没有找到,最后Nuget获取到了 EntityFrameWork.HierarchyId。OK完美运行,查询出来了。

HierarchyId到底是什么呢?

        HierarchyId是SQL Server 2008的一个重要新增特性。主要解决的问题是拥有层次关系的表格。例如文档结构图。我们一般会用一个Document表保存文档数据,而每个文档则又可能会有相应的上级文件夹。以前要得到某个文件的所有上级,或者某个文件所有下级,通常所采取的方法都是递归。SQL Server 2005开始支持的CTE从一定程序上方便了该工作的实现。

       例子就用微软的AdventureWorks2012里面的Production.Document:

image

      创建表语句如下:

CREATE TABLE [Production].[Document](
    [DocumentNode] [hierarchyid] NOT NULL,
    [DocumentLevel]  AS ([DocumentNode].[GetLevel]()),
    [Title] [nvarchar](50) NOT NULL,
    [Owner] [int] NOT NULL,
    [FolderFlag] [bit] NOT NULL,
    [FileName] [nvarchar](400) NOT NULL,
    [FileExtension] [nvarchar](8) NOT NULL,
    [Revision] [nchar](5) NOT NULL,
    [ChangeNumber] [int] NOT NULL,
    [Status] [tinyint] NOT NULL,
    [DocumentSummary] [nvarchar](max) NULL,
    [Document] [varbinary](max) NULL,
    [rowguid] [uniqueidentifier] ROWGUIDCOL  NOT NULL,
    [ModifiedDate] [datetime] NOT NULL,
CONSTRAINT [PK_Document_DocumentNode] PRIMARY KEY CLUSTERED
(
    [DocumentNode] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
UNIQUE NONCLUSTERED
(
    [rowguid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

其中 GetLevel 为 hierarchyid 数据类型的方法;初次之外还有

image

具体大家可以参考msdn官方文档。

那么插入某个节点的数据怎么办呢?

官方也给了办法 就是先查询父节点下最大子节点

然后创建一个新的子节点

declare @HyId hierarchyid=父节点;
declare @NewHyId hierarchyid;

select @NewHyId=@HyId.GetDescendant(MAX(DocumentNode),null) from Document
Where DocumentNode_Id.GetAncestor(1)=@HyId    --创建一个新的节点

select @NewHyId.ToString()

然后将新的节点添加到数据库中。希望微软以后能添加数据类型到CLR和能自动生成新的hierarchyid根据传入的父hierarchyid

当然微软官方有索引优化建议,希望大家去看一下

查询时可以使用SQL类型到C#