Linq 提取树结构
如何使用linq查询和EF检索分层树结构 我的数据库中有用于Linq 提取树结构,linq,entity-framework,linq-to-entities,Linq,Entity Framework,Linq To Entities,如何使用linq查询和EF检索分层树结构 我的数据库中有用于Tab的表,这是一对多对TabGroupBox的表,这是一对多对FieldDetail 我只想根据一些标准检索结构的一部分 比如说,数据库中有以下内容: 选项卡(名称) TabGroupBox(Tab.Name,Name) FieldDetail:(TabGroupBox.Name、Name、FieldStatus) 如果标准是FieldStatus包含“良好”,那么我要查找的结果是: Tab1 -Group1 --Field1 --F
Tab
的表,这是一对多对TabGroupBox
的表,这是一对多对FieldDetail
我只想根据一些标准检索结构的一部分
比如说,数据库中有以下内容:
选项卡(名称)
TabGroupBox(Tab.Name,Name)
FieldDetail:(TabGroupBox.Name、Name、FieldStatus)
如果标准是FieldStatus包含“良好”,那么我要查找的结果是:
Tab1
-Group1
--Field1
--Field4
Tab2
-Group2
--Field2
然而,目前似乎只能得到其中之一
Field1
Field2
Field4
或者复制与字段对应的选项卡
Tab1
Tab1
Tab2
我的非工作查询示例:
Tabs.SelectMany(x => x.TabGroupBoxes.SelectMany(y => y.FieldDetails).Where(z =>
(z.FieldDetailType.Contains("Good")
))
.Select(x => x.TabGroupBox.Tab)
我也尝试过使用.Include()
,但没有成功
此外,如果可能的话,我希望在查询中将db模型投影到我的视图模型上,但这并不像上面那样重要。您最好执行以下操作
context.FieldDetails
.Include(fieldDetail => fieldDetail.GroupBox.Tab) // Use eager loading.
.Where(fieldDetail => fieldDetail.FieldDetailType.Contains("Good")))
.AsEnumerable() // We will do the remaining work client side.
.Select(fieldDetail => fieldDetail.GroupBox.Tab)
.Distinct() // Get rid of duplicate tabs.
.ToList()
不容易的是部分检索相关实体的集合,例如,对于Tab1
,仅检索Group1
,而不检索Group3
。如果你能做到这一点,它会引起一些头痛。如果您提交对Tab1
的更改,该怎么办?是否应该删除Group3
,因为它不在组集合中?它是否应该保留下来,因为您一开始没有加载它?如果您考虑一段时间,就会意识到部分加载相关实体集合的能力会增加很多复杂性,并且在某些情况下会使行为变得非常不直观
如果这还不够,您可以在数据库中创建视图或函数,并将其映射到您的模型,但我已经两年多没有使用实体框架,也没有遵循开发过程,因此我无法向您提供更多详细信息,说明如何实现此目的。看起来您应该使用公共表创建数据库视图表达式并将视图映射到EF。@MarcinJuraszek您的建议如何解决我的问题?我可以在Sql和Linq中组合一个查询,它给了我一个平面表,但这不是我想要的。嘿,grt问题——看起来很简单,直到你看到一个事实,你想要返回一个子集的下叶。我的直觉告诉我linq做这件事可能会变得很麻烦,但千万不要说“永不”——让我做一个Delvehmm——太大的脑筋急转弯,以至于不能在茶歇时间休息。我的直觉告诉我,您需要查看.Any()和.RemoveAll()的组合。将监视线程,因为我有兴趣单独在linq中看到整洁的结果(显然,代码循环解决方案可以工作,但我猜这不是游戏计划)@jimtollan你是对的,代码循环解决方案可以工作,事实上我成功地实现了它,但它没有我所希望的那么好和整洁。稍后我会发布我的循环解决方案,但我想先看看这个问题是否会带来其他问题。
Tab1
Tab1
Tab2
Tabs.SelectMany(x => x.TabGroupBoxes.SelectMany(y => y.FieldDetails).Where(z =>
(z.FieldDetailType.Contains("Good")
))
.Select(x => x.TabGroupBox.Tab)
context.FieldDetails
.Include(fieldDetail => fieldDetail.GroupBox.Tab) // Use eager loading.
.Where(fieldDetail => fieldDetail.FieldDetailType.Contains("Good")))
.AsEnumerable() // We will do the remaining work client side.
.Select(fieldDetail => fieldDetail.GroupBox.Tab)
.Distinct() // Get rid of duplicate tabs.
.ToList()