Reputation: 4137
i have a agency table structure like below in sql
AGENCY_ID AGENCY_NAME PARENT_AGENCY_ID
7 yyyyy 2
8 xxxx 0
9 aaaa 1
6 bbbb 0
1 cccc 7
2 ddddd 0
3 eeeee 1
4 fffff 2
5 ggggg 9
i want a LINQ query to get result set in such away that when i pass a agency id i should get all the sub agencies derived from the agency
for instance if i pass parameter agency id as "7", then i should get all childagencies ,grandchild agencies, great grandchild agencies and so on ,derived from the agency id 7 .For the agency id as "7" the result set would look like below
AGENCY_ID AGENCY_NAME PARENT_AGENCY_ID
7 yyyyy 2
9 aaaa 1
1 cccc 7
3 eeeee 1
5 ggggg 9
how can i achieve this in linq query?
Upvotes: 1
Views: 1643
Reputation: 82096
This is going to require a bit of recursion, which isn't generally optimal, adding a layer of LINQ on top of that is potentially going to make it even slower. My advice would be do this directly in SQL and expose it as an SP which you can call from your application code.
In terms of what your SP would look like, this can be achieved using a CTE e.g.
CREATE PROCEDURE GetAssociatedAgencies
(
@AgencyID int
)
AS
BEGIN
SET NOCOUNT ON;
WITH cte AS
(
SELECT T1.* FROM Agencies as T1
WHERE AGENCY_ID = @AgencyID
UNION ALL
SELECT T2.* FROM Agencies as T2
INNER JOIN cte AS C on T2.PARENT_AGENCY_ID = C.AGENCY_ID
)
SELECT * FROM cte;
END
Stored procedures are generally added as a method on your context so this will be as simple as calling
using (var context = new MyDataContext())
{
var results = context.GetAssociatedAgencies(7);
// query results
}
See it in action.
Upvotes: 1
Reputation: 39085
You write recursive lambda expressions in the following way, and utilize LINQ:
public class Agency
{
public int Id {get; set;}
public int ParentId {get; set;}
public string Name {get; set;}
}
void Main()
{
var list = new List<Agency> {
new Agency { Id = 7, ParentId = 2},
new Agency { Id = 8, ParentId = 0},
new Agency { Id = 9, ParentId = 1},
new Agency { Id = 6, ParentId = 0},
new Agency { Id = 1, ParentId = 7},
new Agency { Id = 2, ParentId = 0},
new Agency { Id = 3, ParentId = 1},
new Agency { Id = 4, ParentId = 2},
new Agency { Id = 5, ParentId = 9}
};
Func<Agency,int, bool> isParent = null;
isParent = (a,i) => a != null &&
(a.Id == i || isParent(list.FirstOrDefault(x => x.Id == a.ParentId),i));
var descendantsOf7 = list.Where(x=>isParent(x,7)).ToList();
}
However, it probably would be more readable and simpler to write a recursive method that does the same thing.
Upvotes: 1