Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ to SQL for self-referencing tables?

I have a self referencing Categories table. Each Category has a CategoryID, ParentCategoryID, CategoryName, etc. And each category can have any number of sub categories, and each of those sub categories can have any number of sub categories, and so and and so forth. So basically the tree can be X levels deep.

Then Products are associated to leaf (sub) Categories. Is there a way to get all the Products for any given Category (which would be all the products associated to all its leaf descendants) using LINQ to SQL?

This feels like a recursive problem. Is it better to used a Stored Procedure instead?

like image 297
Ricky Avatar asked Sep 04 '08 02:09

Ricky


People also ask

Is LINQ to SQL still used?

LINQ to SQL was the first object-relational mapping technology released by Microsoft. It works well in basic scenarios and continues to be supported in Visual Studio, but it's no longer under active development.

How does a LINQ query transform to a SQL query?

LINQ to SQL translates the queries you write into equivalent SQL queries and sends them to the server for processing. More specifically, your application uses the LINQ to SQL API to request query execution. The LINQ to SQL provider then transforms the query into SQL text and delegates execution to the ADO provider.

Is LINQ deprecated?

Dynamic 1.0. 8. This package has been deprecated as it is legacy and is no longer maintained.

What is self reference table in SQL?

Self-referencing table is a table that is a parent and a dependent in the same referential constraint. I. e. in such tables a foreign key constraint can reference columns within the same table.


3 Answers

I don't think linq-to-sql has a good answer to this problem. Since you are using sql server 2005 you can use CTEs to do hierarchical queries. Either a stored procedure or an inline query (using DataContext.ExecuteQuery) will do the trick.

like image 100
liammclennan Avatar answered Sep 20 '22 12:09

liammclennan


Well here is a terrible rushed implementation using LINQ. Don't use this :-)

public IQueryable GetCategories(Category parent)
{
    var cats = (parent.Categories);
    foreach (Category c in cats )
    {
        cats  = cats .Concat(GetCategories(c));
    }
    return a;
}
like image 37
Matt Mitchell Avatar answered Sep 23 '22 12:09

Matt Mitchell


The performant approach is to create an insert/modify/delete trigger which maintains an entirely different table which contains node-ancestor pairs for all ancestors of all nodes. This way, the lookup is O(N).

To use it for getting all products belonging to a node and all of its descendants, you can just select all category nodes which have your target node as an ancestor. After this, you simply select any products belonging to any of these categories.

like image 26
Sander Avatar answered Sep 20 '22 12:09

Sander