[英]EF Core - How to setup many-to-many for same entity that already has a one-to-many relationship
[英]EF Core how select entity with many-to-many relationship
我是這樣的表結構
描述:
user有許多用戶配置文件,user_profile表連接用戶和配置文件表。(用戶和配置文件表之間存在多對多的關系)
用戶>一個一對多> user_profiles>一個對一>型材
user> many user_profiles>一個配置文件
問題:
如何使用linq選擇具有配置文件的用戶。
樣品:
var user=cbContext.user.include("user_profiles").include("profiles").Where(predicate).FirstOrDefault();
找到了答案
dbContext.Users
.Include(user => user.UserProfiles)
.ThenInclude(userProfiles => userProfiles.Profile)
.Where(predicate)
.FirstOrDefault();
如果你有完整的實體框架,那么多對多的設計類似於:
class User
{
public int Id {get; set;}
// every User has zero or more Profiles (many-to-many)
public virtual ICollection<Profile> Profiles {get; set;}
...
}
class Profile
{
public int Id {get; set;}
// every Profile belongs to zero or more Users (many-to-many)
public virtual ICollection<User> Userss {get; set;}
...
}
如果您的課程設計如此,並且您希望“用戶......以及他們的個人資料”,您可以使用這些集合並選擇您計划使用的屬性:
using (var dbContext = new MyDbContext(...))
{
var requestedUsers = dbContext.Users
.Where(user => ...) // only if you don't want all Users
.Select(user => new
{ // Select only the properties you plan to use:
Id = user.Id,
Name = user.Name,
...
Profiles = user.Profiles
.Where(profile => ...) // only if you don't want all profiles
.Select(profile => new
{
Name = profile.Name,
...
})
.ToList(),
})
數據庫查詢的較慢部分之一是將所選數據從數據庫管理系統傳輸到您的進程。 因此,明智的做法是將要傳輸的數據限制為實際計划使用的數據。
Include
將選擇所包含對象的所有屬性,包括主鍵和外鍵。 即使您只打算使用一些,也Include a Collection
將選擇完整的集合。
建議:如果您計划更改提取的數據,則僅使用
Include
。 使用Select
更快。 僅Select
您實際計划使用的屬性
如果您不能使用ICollection,請使用(組)加入
我從一些人了解到,當您使用EF-core時,您無法使用virtual ICollections
。 在這種情況下,您必須自己執行GroupJoin
dbContext.Users
.Where(user => ...)
.GroupJoin(dbContext.UserProfiles, // GroupJoin the users with the UserProfiles
user => user.Id // from every user take the Id
userProfile => userProfile.UserId, // from every userProfile take the UserId
(user, userProfiles) => new // when thay match,
{ // take the user and its matching UserProfiles
UserId = user.Id, // again: select only properties you plan to use
UserName = user.Name,
...
// for the Profiles, do a new Join with the Profiles
Profiles = userProfiles.Join(dbContext.Profiles, // join with Profiles
userProfile => userProfile => profileId // from the userProfile take profileId
profile => profile.Id, // from the Profile take the Id
(userProfile, profile) => new // when they match, make an object
{ // again: use only properties you plan to use
ProfileId = profile.Id,
ProfileName = profile.Name,
...
})
.ToList(),
});
小心:沒有任何配置文件,您將無法獲得用戶!
這是一個內部聯接。
如果您還希望用戶沒有配置文件,請使用Stackoverflow中所述的Left-Outer-GroupJoin向下滾動以獲得排名最高的答案,這比選擇的答案更好
除了你自己對lambda的回答和ThenInclude
的使用,這是我對n到n關系的簡單查詢的首選版本,你還可以使用字符串來指定包含。
您只需要編寫用點分隔的屬性的“路徑” .
像這樣 :
dbContext.Users
.Include("UserProfiles.Profile")
.Where(predicate)
.FirstOrDefault();
它適用於1對1,1對多,多對多關系相同。
當你有深層的實體包含時(但你丟失了編譯時檢查)它很有用
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.