Recursive/Hierarchical 在 LINQ 中查询
Recursive/Hierarchical Query in LINQ
场景是,
我正在使用 EntityFrame Work 6。我有一个数据库 table 具有以下结构。
cat_id geo_id parent_id geo_name
Root 1 NULL Pakistan
Province 2 1 Punjab
District 3 2 Attock
City 4 3 Attock
City 5 3 Fateh Jang
City 6 3 Hasan Abdal
Table 具有关系形式的分层数据,如您所见。
我想遍历这个层次结构,想要特定的 parent 级别,如果我在 geo_id 6
那么我想去 parent_id 3
并获得值 Attock
或想要前往 parent_id 2
并想要获得价值 Punjab
。
这个故事的寓意是,站在任何 child,想要遍历到指定的 parent 或大 parent,而不是整个层次结构。下面是我试过的代码,但它只给我直接 parent.
更简短地说,想要一个 LINQ 查询,它将 return 指定的 parent 或 grand parent 的名称,例如。我可以问我的问题,"hey! im Hasan Abdal(City)
,tell me my Province
"
Province = (from cp in db.geo_hierarchy
join mp in db.geo_hierarchy on cp.parent_id equals mp.geo_id
where cp.geo_name == risk.geo_hierarchy.geo_name
select mp.geo_name).FirstOrDefault()
查看下面的完整代码,它在 LINQ 查询的 select
子句中使用
Risklists = (from risk in db.risk_cat_detail
where risk.occurance_date.Value.Year==2014 && risk.occurance_date.Value.Month>=6 && risk.occurance_date.Value.Month<=9
select new risk_cat_detail_contract()
{
cat_id = risk.cat_id,
catdesc = risk.category_main.cat_name,
risk_cat_detail_id = risk.risk_cat_detail_id,
trans_date = risk.trans_date.Value,
occurance_date = risk.occurance_date.Value,
occurance_time = risk.occurance_time,
geo_id = risk.geo_id,
geo_desc = risk.geo_hierarchy.geo_name,
Province = (from cp in db.geo_hierarchy
join mp in db.geo_hierarchy on cp.parent_id equals mp.geo_id
where cp.geo_name == risk.geo_hierarchy.geo_name
select mp.geo_name).FirstOrDefault()
}).ToList<risk_cat_detail_contract>();
帮帮我,谢谢
试试这个:
var geo_hierarchy = new []
{
new { cat_id = "Root", geo_id = 1, parent_id = (int?)null, geo_name = "Pakistan", },
new { cat_id = "Province", geo_id = 2, parent_id = (int?)1, geo_name = "Punjab", },
new { cat_id = "District", geo_id = 3, parent_id = (int?)2, geo_name = "Attock", },
new { cat_id = "City", geo_id = 4, parent_id = (int?)3, geo_name = "Attock", },
new { cat_id = "City", geo_id = 5, parent_id = (int?)3, geo_name = "Fateh Jang", },
new { cat_id = "City", geo_id = 6, parent_id = (int?)3, geo_name = "Hasan Abdal", },
};
var map = geo_hierarchy.ToDictionary(x => x.geo_id);
Func<int, string, string> up = null;
up = (geo_id, cat_id) =>
{
var record = map[geo_id];
return
record.cat_id == cat_id
? record.geo_name
: (record.parent_id.HasValue
? up(record.parent_id.Value, cat_id)
: null);
};
var result = up(5, "Province"); // -> "Punjab"
场景是,
我正在使用 EntityFrame Work 6。我有一个数据库 table 具有以下结构。
cat_id geo_id parent_id geo_name
Root 1 NULL Pakistan
Province 2 1 Punjab
District 3 2 Attock
City 4 3 Attock
City 5 3 Fateh Jang
City 6 3 Hasan Abdal
Table 具有关系形式的分层数据,如您所见。
我想遍历这个层次结构,想要特定的 parent 级别,如果我在 geo_id 6
那么我想去 parent_id 3
并获得值 Attock
或想要前往 parent_id 2
并想要获得价值 Punjab
。
这个故事的寓意是,站在任何 child,想要遍历到指定的 parent 或大 parent,而不是整个层次结构。下面是我试过的代码,但它只给我直接 parent.
更简短地说,想要一个 LINQ 查询,它将 return 指定的 parent 或 grand parent 的名称,例如。我可以问我的问题,"hey! im Hasan Abdal(City)
,tell me my Province
"
Province = (from cp in db.geo_hierarchy
join mp in db.geo_hierarchy on cp.parent_id equals mp.geo_id
where cp.geo_name == risk.geo_hierarchy.geo_name
select mp.geo_name).FirstOrDefault()
查看下面的完整代码,它在 LINQ 查询的 select
子句中使用
Risklists = (from risk in db.risk_cat_detail
where risk.occurance_date.Value.Year==2014 && risk.occurance_date.Value.Month>=6 && risk.occurance_date.Value.Month<=9
select new risk_cat_detail_contract()
{
cat_id = risk.cat_id,
catdesc = risk.category_main.cat_name,
risk_cat_detail_id = risk.risk_cat_detail_id,
trans_date = risk.trans_date.Value,
occurance_date = risk.occurance_date.Value,
occurance_time = risk.occurance_time,
geo_id = risk.geo_id,
geo_desc = risk.geo_hierarchy.geo_name,
Province = (from cp in db.geo_hierarchy
join mp in db.geo_hierarchy on cp.parent_id equals mp.geo_id
where cp.geo_name == risk.geo_hierarchy.geo_name
select mp.geo_name).FirstOrDefault()
}).ToList<risk_cat_detail_contract>();
帮帮我,谢谢
试试这个:
var geo_hierarchy = new []
{
new { cat_id = "Root", geo_id = 1, parent_id = (int?)null, geo_name = "Pakistan", },
new { cat_id = "Province", geo_id = 2, parent_id = (int?)1, geo_name = "Punjab", },
new { cat_id = "District", geo_id = 3, parent_id = (int?)2, geo_name = "Attock", },
new { cat_id = "City", geo_id = 4, parent_id = (int?)3, geo_name = "Attock", },
new { cat_id = "City", geo_id = 5, parent_id = (int?)3, geo_name = "Fateh Jang", },
new { cat_id = "City", geo_id = 6, parent_id = (int?)3, geo_name = "Hasan Abdal", },
};
var map = geo_hierarchy.ToDictionary(x => x.geo_id);
Func<int, string, string> up = null;
up = (geo_id, cat_id) =>
{
var record = map[geo_id];
return
record.cat_id == cat_id
? record.geo_name
: (record.parent_id.HasValue
? up(record.parent_id.Value, cat_id)
: null);
};
var result = up(5, "Province"); // -> "Punjab"