Tôi sẽ thiết lập chế độ xem và chức năng dựa trên bảng được liên kết dựa trên CTE. Lý do của tôi cho điều này là, trong khi bạn có thể thực hiện logic ở phía ứng dụng, điều này sẽ liên quan đến việc gửi dữ liệu trung gian qua dây để tính toán trong ứng dụng. Sử dụng trình thiết kế DBML, khung nhìn dịch thành một thực thể Table. Sau đó bạn có thể kết hợp hàm với thực thể Table và gọi phương thức được tạo trên DataContext để lấy ra các đối tượng thuộc kiểu được định nghĩa bởi khung nhìn. Sử dụng hàm dựa trên bảng cho phép công cụ truy vấn đưa các tham số của bạn vào tài khoản trong khi xây dựng bộ kết quả thay vì áp dụng điều kiện trên tập kết quả được xác định bởi khung nhìn sau khi thực tế.
CREATE TABLE [dbo].[hierarchical_table](
[id] [int] IDENTITY(1,1) NOT NULL,
[parent_id] [int] NULL,
[data] [varchar](255) NOT NULL,
CONSTRAINT [PK_hierarchical_table] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE VIEW [dbo].[vw_recursive_view]
AS
WITH hierarchy_cte(id, parent_id, data, lvl) AS
(SELECT id, parent_id, data, 0 AS lvl
FROM dbo.hierarchical_table
WHERE (parent_id IS NULL)
UNION ALL
SELECT t1.id, t1.parent_id, t1.data, h.lvl + 1 AS lvl
FROM dbo.hierarchical_table AS t1 INNER JOIN
hierarchy_cte AS h ON t1.parent_id = h.id)
SELECT id, parent_id, data, lvl
FROM hierarchy_cte AS result
CREATE FUNCTION [dbo].[fn_tree_for_parent]
(
@parent int
)
RETURNS
@result TABLE
(
id int not null,
parent_id int,
data varchar(255) not null,
lvl int not null
)
AS
BEGIN
WITH hierarchy_cte(id, parent_id, data, lvl) AS
(SELECT id, parent_id, data, 0 AS lvl
FROM dbo.hierarchical_table
WHERE (id = @parent OR (parent_id IS NULL AND @parent IS NULL))
UNION ALL
SELECT t1.id, t1.parent_id, t1.data, h.lvl + 1 AS lvl
FROM dbo.hierarchical_table AS t1 INNER JOIN
hierarchy_cte AS h ON t1.parent_id = h.id)
INSERT INTO @result
SELECT id, parent_id, data, lvl
FROM hierarchy_cte AS result
RETURN
END
ALTER TABLE [dbo].[hierarchical_table] WITH CHECK ADD CONSTRAINT [FK_hierarchical_table_hierarchical_table] FOREIGN KEY([parent_id])
REFERENCES [dbo].[hierarchical_table] ([id])
ALTER TABLE [dbo].[hierarchical_table] CHECK CONSTRAINT [FK_hierarchical_table_hierarchical_table]
Để sử dụng nó, bạn sẽ làm điều gì đó giống như - giả định một số đề án đặt tên hợp lý:
using (DataContext dc = new HierarchicalDataContext())
{
HierarchicalTableEntity h = (from e in dc.HierarchicalTableEntities
select e).First();
var query = dc.FnTreeForParent(h.ID);
foreach (HierarchicalTableViewEntity entity in query) {
...process the tree node...
}
}
Tôi đã thử một chức năng như thế này, và nó có vẻ là con đường để đi. Và nó có thể được gọi từ LINQ, gắn liền với datacontext. Ngoài ra, tại sao cả chế độ xem và chức năng? - chúng dường như trùng lặp – Anthony
Hàm không ánh xạ cùng một lược đồ như bảng. Nó bao gồm các cấp độ. Nếu bạn không có cột được thêm vào, bạn có thể ánh xạ nó trực tiếp lên bảng. Tôi cho rằng mức độ trong hệ thống phân cấp là quan trọng. – tvanfosson