2008-09-04 38 views
5

Tôi có bảng Danh mục tham chiếu tự. Mỗi loại có một CategoryID, ParentCategoryID, CategoryName, vv Và mỗi thể loại có thể có bất kỳ số lượng các loại phụ, và mỗi thể loại phụ có thể có bất kỳ số lượng các loại phụ, và như vậy và vv. Vì vậy, về cơ bản cây có thể là cấp độ X sâu.LINQ to SQL cho các bảng tự tham khảo?

Sau đó, các sản phẩm được liên kết với các loại lá (phụ). Có cách nào để có được tất cả các Sản phẩm cho bất kỳ Danh mục cụ thể nào (có phải tất cả các sản phẩm liên quan đến tất cả các con cháu của nó) sử dụng LINQ to SQL không?

Điều này giống như một vấn đề đệ quy. Sử dụng thủ tục lưu trữ có tốt hơn không?

Trả lời

3

Tôi không nghĩ linq-to-sql có câu trả lời hay cho vấn đề này. Vì bạn đang sử dụng máy chủ sql 2005, bạn có thể sử dụng các CTE để thực hiện các truy vấn phân cấp. Một thủ tục được lưu trữ hoặc truy vấn nội tuyến (sử dụng DataContext.ExecuteQuery) sẽ thực hiện thủ thuật.

1

Đây là một triển khai vội vã khủng khiếp sử dụng LINQ. Không sử dụng :-) này

public IQueryable GetCategories(Category parent) 
{ 
    var cats = (parent.Categories); 
    foreach (Category c in cats) 
    { 
     cats = cats .Concat(GetCategories(c)); 
    } 
    return a; 
} 
1

Phương pháp performant là tạo ra một chèn/sửa đổi/xóa kích hoạt mà duy trì một bảng hoàn toàn khác nhau, trong đó có cặp node-tổ tiên cho tất cả tổ tiên của tất cả các nút. Bằng cách này, tra cứu là O (N).

Để sử dụng nó để nhận tất cả các sản phẩm thuộc về một nút và tất cả các nút của nó, bạn chỉ có thể chọn tất cả các nút danh mục có nút đích của bạn làm tổ tiên. Sau đó, bạn chỉ cần chọn bất kỳ sản phẩm nào thuộc bất kỳ danh mục nào trong số này.

1

Cách tôi xử lý việc này là sử dụng một số phương pháp mở rộng (bộ lọc). Tôi đã viết lên một số mã mẫu từ một dự án mà tôi đã thực hiện điều này. Nhìn cụ thể tại các dòng nơi tôi đang cư trú một đối tượng ParentPartner và một danh sách SubPartners.

public IQueryable<Partner> GetPartners() 
     { 
      return from p in db.Partners 
        select new Partner 
        { 
         PartnerId = p.PartnerId, 
         CompanyName = p.CompanyName, 
         Address1 = p.Address1, 
         Address2 = p.Address2, 
         Website = p.Website, 
         City = p.City, 
         State = p.State, 
         County = p.County, 
         Country = p.Country, 
         Zip = p.Zip, 
         ParentPartner = GetPartners().WithPartnerId(p.ParentPartnerId).ToList().SingleOrDefault(), 
         SubPartners = GetPartners().WithParentPartnerId(p.PartnerId).ToList() 
        }; 
     } 


public static IQueryable<Partner> WithPartnerId(this IQueryable<Partner> qry, int? partnerId) 
     { 
      return from t in qry 
        where t.PartnerId == partnerId 
        select t; 
     } 

public static IQueryable<Partner> WithParentPartnerId(this IQueryable<Partner> qry, int? parentPartnerId) 
     { 
      return from p in qry 
        where p.ParentPartner.PartnerId == parentPartnerId 
        select p; 
     } 
+0

Tôi nghĩ đây là một ý tưởng tuyệt vời, nhưng tôi gặp lỗi khi cố triển khai điều này. Nó nói rằng phương thức mở rộng "WithPartnerId" không có bản dịch được hỗ trợ cho SQL. Bất kỳ ý tưởng? –