[英]Parent child relation in Linq query
因此,您具有三個表: TestTags
表, TestParents
表和帶有TestChildren
的表。
每個TestTag
都有零個或多個TestChildren
; 每個TestChild
使用外鍵完全屬於一個TestTag
。 直接的一對多關系
每個TestParent
還具有零個或多個TestChildren
; 每個TestChild
都有一個使用外鍵的TestParent
。
如果您遵循實體框架代碼優先約定 ,那么您將擁有類似於
class TestTag
{
public int Id {get; set;}
... // other properties
// every TestTag has zero or more TestChildren (one-to-many)
public virtual ICollection<TestChild> TestChildren {get; set;}
}
class TestParent
{
public int Id {get; set;}
... // other properties
// every TestParent has zero or more TestChildren (one-to-many)
public virtual ICollection<TestChild> TestChildren {get; set;}
}
class TestChild
{
public int Id {get; set;}
... // other properties
// every TestChild has exactly one TestParent using foreign key
public int TestParentId {get; set;}
public virtual TestParent TestParent {get; set;}
// every TestChild has exactly one TestTag using foreign key
public int TestTagId {get; set;}
public virtual TestTag TestTag {get; set;}
}
在實體框架中,表的列由非虛擬屬性表示。 虛擬屬性表示表之間的關系(一對多,多對多,...)
這樣,TestTag 4和TestParent 5可以有兩個子代。 如果您不想要,請考慮創建組合的主鍵[TestTagId,TestParentId]
如果TestChild除了外鍵之外沒有其他屬性,那么實際上您將在TestTag和TestParent之間創建多對多關系。 在這種情況下,您不必提及TestChild表。
為了完整起見,DbContext:
class MyDbContext : DbContext
{
public DbSet<TestTag> TestTags {get; set;}
public DbSet<TestParent> TestParents {get; set;}
public DbSet<TestChild> TestChildren {get; set;}
}
這是實體框架檢測您的關系以及主鍵和外鍵所需要知道的全部內容。 因為我遵循了約定的屬性,所以也不需要流利的API,除非是因為非標准的復數形式Children
。
所以我可以加入TestParent和TestChild表
好了,您可以執行(group-)join,但是使用ICollections
通常更容易
給我...的TestParents及其所有的TestChildren和TestTags ...
var result = dbContext.TestParents
.Where(parent => ...) // if you don't want all testParents
.Select(parent => new
{
// select only the properties you plan to use
Id = parent.Id,
Name = parent.Name,
Children = parent.TestChildren
.Where(child => child.TestTag.Name = "My Test Tag Name")
.Select(child => new
{
Name = child.TestTag.Name,
...
})
.ToList(),
});
有些人喜歡改用GroupJoin。 如果您希望這樣做,並且可以說服項目負責人與使用ICollections相比,GroupJoin具有更好的可讀性/可測試性/可維護性,則可以執行以下操作:
var result = dbContext.TestParents.GroupJoin(dbContext.TestChildren,
parent => parent.Id, // from each parent take the Id
child => child.ParentId, // from each child take the ParentId
// resultSelector:
(parent, children) => new
{
// Parent Properties:
Id = parent.Id,
...
// GroupJoin the collection of child properties with the TestTags:
children.GroupJoin(dbContext.TestTags,
child => child.TestTagId, // from each TestChild take the TestTagId
tag => tag.Id, // from each TestTag take the Id
(child, tagsOfThisChild) => new
{
// desired Child properties
...
TestTags = tagsOfThisChild.Select(tag => new
{
Id = tag.Id,
...
})
.ToList(),
})
.ToList(),
});
恕我直言:這看起來太可怕了!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.