Database 自引用表的LINQ到SQL?

Database 自引用表的LINQ到SQL?,database,linq-to-sql,Database,Linq To Sql,我有一个自引用类别表。每个类别都有一个CategoryID、ParentCategoryID、CategoryName等,每个类别都可以有任意数量的子类别,每个子类别都可以有任意数量的子类别,依此类推。所以基本上树可以是X层深 然后将产品关联到叶(子)类别。是否有一种方法可以使用LINQtoSQL获取任何给定类别的所有产品(即与其所有叶子子体关联的所有产品) 这感觉像是一个递归问题。使用存储过程更好吗?这里是一个使用LINQ的糟糕的实现。 不要使用此:-) performant方法是创建一个in

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

然后将产品关联到叶(子)类别。是否有一种方法可以使用LINQtoSQL获取任何给定类别的所有产品(即与其所有叶子子体关联的所有产品)


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

这里是一个使用LINQ的糟糕的实现。 不要使用此:-)


performant方法是创建一个insert/modify/delete触发器,该触发器维护一个完全不同的表,其中包含所有节点的所有祖先的节点-祖先对。这样,查找是O(N)


要使用它获取属于某个节点及其所有子节点的所有产品,只需选择以目标节点为祖先的所有类别节点即可。在此之后,您只需选择属于这些类别的任何产品。

我认为LINQtoSQL并不能很好地解决这个问题。因为您使用的是SQLServer2005,所以可以使用CTE进行分层查询。存储过程或内联查询(使用DataContext.ExecuteQuery)都可以做到这一点

我处理这个问题的方法是使用一些扩展方法(过滤器)。我已经从一个项目中编写了一些示例代码,我已经实现了这个。具体看一下我填充ParentPartner对象和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;
        }
publicIQueryable GetPartners()
{
从数据库中的p返回
选择新的合作伙伴
{
PartnerId=p.PartnerId,
CompanyName=p.CompanyName,
地址1=p.Address1,
地址2=p.Address2,
网站,
城市,
状态=p.状态,
郡,
国家,国家,
Zip=p.Zip,
ParentPartner=GetPartners().WithPartnerId(p.ParentPartnerId).ToList().SingleOrDefault(),
SubPartners=GetPartners().WithParentPartnerId(p.PartnerId).ToList()
};
}
带有partnerId的公共静态IQueryable(此IQueryable qry,int?partnerId)
{
在qry中从t返回
其中t.PartnerId==PartnerId
选择t;
}
带有parentPartnerId的公共静态IQueryable(此IQueryable qry,int?parentPartnerId)
{
从qry中的p返回
其中p.ParentPartner.PartnerId==parentPartnerId
选择p;
}

我认为这是一个很好的想法,但我在尝试实现这一点时遇到了一个错误。它说“WithPartnerId”扩展方法不支持到SQL的转换。有什么想法吗?
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;
        }