LINQ to SQL自引用表?
时间:2020-03-05 18:47:26 来源:igfitidea点击:
我有一个自引用类别表。每个类别都有一个CategoryID,ParentCategoryID,CategoryName等。每个类别可以具有任意数量的子类别,并且每个子类别可以具有任意数量的子类别,依此类推。所以基本上树可以是X层深。
然后将产品与叶子(子)类别相关联。有没有一种方法可以使用LINQ to SQL来获取给定类别的所有产品(与该产品的所有后代关联的所有产品)?
这感觉像是一个递归问题。改用存储过程更好吗?
解决方案
回答
好吧,这是一个使用LINQ的紧急解决方案。
不要使用这个:-)
public IQueryable GetCategories(Category parent) { var cats = (parent.Categories); foreach (Category c in cats ) { cats = cats .Concat(GetCategories(c)); } return a; }
回答
高性能方法是创建一个插入/修改/删除触发器,该触发器维护一个完全不同的表,该表包含所有节点的所有祖先的节点祖先对。这样,查找为O(N)。
要使用它来获取属于某个节点及其所有后代的所有产品,我们只需选择将目标节点作为祖先的所有类别节点即可。此后,我们只需选择属于这些类别中任何一个的任何产品。
回答
我认为linq-to-sql对这个问题没有很好的答案。由于我们使用的是sql server 2005,因此可以使用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; }