更新 这是我与 @Slauma 讨论过的以下评论:
Because I need to get all locations that are connected to passed root category. As you can see if I pass 2 and some location have category 44 and 44 is child of 32 which is child of 2 I need to get this location. LocationCategory is N:N table in database between Locations and PlaceCategories. Not important but can give a better picture. I have a map and markers on that map. I can click on Education(id:2) link and I need to get all markers where root of location category is '2' (like on foursquare.com map)
我在数据库中有一个自引用表。 所以我创建了以下对象:
public class PlaceCategory
{
public int PlaceCategoryId { get; set; }
public string Name{ get; set; }
public int? ParentId { get; set; }
public virtual PlaceCategory Parent { get; set; }
public virtual ICollection<PlaceCategory> Children { get; set; }
public string Icon { get; set; }
}
因为 Location 对象可以有多个类别,所以我有 LocationCategory 对象:
public class LocationCategory
{
[Key, Column(Order = 1)]
public int LocationId { get; set; }
[Key, Column(Order = 2)]
public int PlaceCategoryId { get; set; }
public Guid UserId { get; set; }
public DateTime CreatedOnDate { get; set; }
public bool IsPrimary { get; set; }
public virtual Location Location { get; set; }
public virtual PlaceCategory PlaceCategory { get; set; }
public virtual User User { get; set; }
}
位置对象有:
public class Location
{
...
public virtual ICollection<LocationCategory> LocationCategories { get; set; }
...
在自引用表的数据库中,我有:
root: Education (id:2, parentId:null)
child1: School(id:32, parentId:2)
child2: Elementary(id:42,parentId:32), High(id:43,parentId:32), Higher(id:44,parentId:32) etc.
我必须根据传递的根类别获取位置列表。
var model = locationRepository.GetLocationss().Where(x => x.LocationCategories???); // but it's a list and don't know how to check top most parent here?
因此,如果我通过“2”,我应该获得类别为 2,32,42,43,44 的所有项目
最佳答案
Entity Framework 不支持此功能,除非您将 rootCategoryId
添加到每个 PlaceCategory
并在检索位置时过滤该属性,但一旦您有更深的嵌套并且这种方法将会失败,您可能需要获取某些非根类别(但有其自己的父级)的所有位置。在这种情况下,存储根目录将无济于事。
这个问题的概括称为分层或递归查询。这是可以遍历层次结构并获取所有需要的嵌套记录的查询。可以使用 Common Table Expression alias CTE 通过 SQL 来做到这一点(需要 SQL Server 2005 或更高版本)。您可以创建这样的查询并直接通过dbContext.Database.SqlQuery
执行它。
如果使用 .NET 4.5 和 EDMX(数据库优先)的 EF 5.0,您还可以在 SQL Server 中将查询实现为表值函数,将其映射到 EDMX 中并在 Linq 查询中使用它。
关于database - 如何获取自引用对象中最顶层的父级,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12447879/