我是linq的新手,我正在尝试找到一种方法来返回一个给定父节点的父节点和一个List(子节点)以及所有子节点。我有一个Locations表,其中包含字段LocationID
、ParentLocationID
、LocationName
。数据示例如下:
ABC
--ABC1
--ABC2
----DEF1
----DEF2
----DEF3
--ABC3
----DEF4
------GHI1
------GHI2
----DEF5
--ABC4
...
给定该数据,如果选择的父项是'ABC',我希望返回所有行,因为所有子项都在它下面。但是,如果选择父项'ABC3',它将返回DEF4、GHI1、GHI2、DEF5。
我已经研究了这些SO问题,但对于如何创建此陈述仍感到困惑:
Find all descendants in self-referencing (parent-child) hierarchical tree
LINQ to SQL - Self Join Child to Parent (Same Table)
以下是我尝试过的操作,但出现错误:
public ActionResult Index()
{
var loc = GetChild(346);
return View(loc);
}
public IEnumerable<Location> GetChild(int id)
{
DBEntities db = new DBEntities();
var locations = db.Locations.Where(x => x.ParentLocationID == id || x.LocationID == id).Union(
db.Locations.Where(x => x.ParentLocationID == id).SelectMany(y => GetChild(y.LocationID)));
return locations;
}
Location
类为:
public class Location
{
public Location();
public virtual ICollection<SimSystem> SimSystems { get; set; }
public virtual ICollection<LocationAddress> LocationAddresses { get; set; }
public virtual LocationType LocationType { get; set; }
public virtual ICollection<CustomerUser> CustomerUsers { get; set; }
public virtual ICollection<AppUserLocation> AppUserLocations { get; set; }
public int LocationTypeID { get; set; }
public DateTime? InstallDate { get; set; }
public string AltPhone { get; set; }
public string OfficePhone { get; set; }
public int? PrimaryAddressID { get; set; }
public int? ParentLocationID { get; set; }
public string LocationName { get; set; }
public string LocationName2 { get; set; }
public int LocationID { get; set; }
public virtual Address Address { get; set; }
}
错误为:
LINQ to Entities无法辨识方法,而且这个方法无法转译为存放区运算式。
3条答案
按热度按时间nnsrf1az1#
你能试试这个吗?
62o28rlo2#
首先,您可能希望将
DBEntities
从递归方法中删除,这样会导致在数据库上建立太多连接,并导致内存泄漏。至于异常。它声明对
GetChild(int);
的调用无法转换为linq到sql表达式。如果你有你想生成的sql,我可以帮助你将其转换为linq。编辑:
所以我能够重新创建你的代码。这不是最优的,因为它会用sql查询多次调用数据库。
e5nszbig3#
因此,当我自己试图弄清楚这一点并失败时,我做了一些研究。我看到的大多数文章都说,这在Linq的单个查询中是不可能的。
你可以做的一件事就是收集所有的对象ID,然后只从中获取你需要的对象,然后用这些对象在内存中构建一个树。获取ID应该很快,特别是索引。
例如
List<int> locationIDs = db.Locations.Where(x => x.ParentLocationID == id || x.LocationID == id).Select(x => x.LocationID).ToList();
然后您可以
var locations = db.Locations.Where(x => locationIDs.Contains(x.LocationID);
然后使用一个普通的递归方法来构建树。然而,我还想提一下我发现的一个扩展方法,据说它可以为你做这件事。这个描述看起来非常详细,有信息图表之类的。http://www.scip.be/index.php?Page=ArticlesNET23