关于数据库:LINQ to SQL用于自引用表?

关于数据库:LINQ to SQL用于自引用表?

LINQ to SQL for self-referencing tables?

我有一个自引用类别表。 每个类别都有一个CategoryID,ParentCategoryID,CategoryName等。每个类别可以具有任意数量的子类别,并且每个子类别可以具有任意数量的子类别,依此类推。 所以基本上树可以是X层深。

然后将产品与叶子(子)类别关联。 有没有一种方法可以使用LINQ to SQL来获取给定类别的所有产品(与该产品的所有后代关联的所有产品)?

这感觉像是一个递归问题。 改用存储过程更好吗?


我认为linq-to-sql对这个问题没有很好的答案。由于您使用的是sql server 2005,因此可以使用CTE进行层次查询。存储过程或内联查询(使用DataContext.ExecuteQuery)都可以解决问题。


好吧,这是一个使用LINQ的紧急解决方案。
不要使用这个:-)

1
2
3
4
5
6
7
8
9
public IQueryable GetCategories(Category parent)
{
    var cats = (parent.Categories);
    foreach (Category c in cats )
    {
        cats  = cats .Concat(GetCategories(c));
    }
    return a;
}


我处理此问题的方法是使用一些扩展方法(过滤器)。我已经从实现了该项目的项目中编写了一些示例代码。专门查看我要填充ParentPartner对象和SubPartners列表的行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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;
        }

高性能方法是创建一个插入/修改/删除触发器,该触发器维护一个完全不同的表,该表包含所有节点的所有祖先的节点-祖先对。这样,查找为O(N)。

要使用它来获取属于一个节点及其所有后代的所有产品,您只需选择将目标节点作为祖先的所有类别节点即可。之后,您只需选择属于这些类别中任何一个的任何产品。


推荐阅读