[英]Use Linq to return all objects in a list where the object's sub-object-list property contains all values of an int list
[英]LINQ - EF Core - Return object that contains two objects (referenced by property) in nested list
我知道有一百萬個 LINQ 問題,所以很抱歉問這個問題。 我環顧四周,我找不到正確的答案。 我懷疑這很容易,但我是 LINQ 和 EF 內核的新手。
我有以下從數據庫查詢返回的 Room 類型列表(為簡潔起見,我只包括一個):
[
{
"roomId": 2,
"roomName": "test",
"users": [
{
"userId": 2,
"username": "seconduser",
"password": "demo",
"token": null,
"refreshToken": null,
"alias": "test",
"friends": null
},
{
"userId": 3,
"username": "thirduser",
"password": "demo",
"token": null,
"refreshToken": null,
"alias": "test",
"friends": null
}
]
}
]
偉大的。 我想要一個 LINQ 查詢(最好是流利的語法,但我很感激任何幫助),它將用更多房間查詢這個列表並只返回一個(我知道只有一個)滿足以下標准:
房間里只有兩個用戶,並且這兩個用戶都是通過傳入方法的 userId 來標識的。
因此,如果方法接收到以下 object:
{
"friendId": 1,
"requestUserId": 3
}
上面引用的房間將被退回,其他房間不退還。
我希望這很清楚。
提前致謝!
編輯 - 很公平,我現在包括一些讓我更接近的嘗試
我嘗試填充兩個用戶,以便我可以詢問 room.Users.Contains() 是否像這樣:
var requestingUser = UserService.GetSingleUser(request.RequestUserId);
var friendUser = UserService.GetSingleUser(srequest.FriendId);
var test = allRooms.FirstOrDefault(room => room.Users.Count == 2 && room.Users.Contains(friendUser) && room.Users.Contains(requestingUser);
然而,用戶的比較並沒有通過 go。 這只是我如何填充用戶的問題嗎? 無論如何,我知道我不應該那樣做。
然后我嘗試了在方向方面似乎是正確的方法,就像這樣比較 ID:
var test = allRooms.First(room => room.Users.Any(user =>
user.userId == request.FriendId && user.userId == request.RequestUserId));
但這會返回 null,但我已經確認有一個房間滿足我指定的條件。
給我帶來麻煩的是 EF 核心生成了一個我不熟悉的數據庫模式。 僅在 SQL 中,我將有表 ROOM、USER、ROOMUSER 和內部加入 ROOMUSER,其中 USER.id 都存在......並且不同,或者類似的東西。
進一步編輯:
我在下面包含了我用來構建數據庫的模型。 最初我沒有,因為我包含的 JSON 是查詢所有房間並包括其用戶(房間內的 ICollection)的結果。
public class User
{
public int UserId { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string Token { get; set; }
public string RefreshToken { get; set; }
public string Alias { get; set; }
public ICollection<User> Friends { get; set; }
}
public class Room
{
public int RoomId { get; set; }
public string RoomName { get; set; }
public ICollection<User> Users { get; set; }
}
因此,正如我所描述的,如果我手工制作表格會是什么樣子,這個想法是 User 和 Room 是不同的實體(主要實體),並且會有一個連接表格來暗示它們之間的關系。 從概念上講,用戶在房間中。
以下 LINQ 返回的初始 JSON 也可能使事情更清楚:
var allRooms = db.Rooms.Include(x => x.Users).ToList();
因此,要求具有上述條件的房間應該不會太難。
誠然,正如我所說,我從未使用過 EF 內核,也幾乎沒有使用過 LINQ。 我可能犯了一個愚蠢的錯誤......
這個很近
room => room.Users.Any(user =>
user.userId == request.FriendId && user.userId == request.RequestUserId)
但需要一些調整
並且 ( &&
) 運算符不合適 - id 不能同時等於兩個傳遞的 id。 它應該是一個或另一個,即您需要的是 Or ( ||
) 運算符
user.userId == request.FriendId || user.userId == request.RequestUserId
Any
也不合適。 它將返回一個房間,其中只有一個通過的用戶,或兩者兼有,但其中還有其他用戶。 你需要的是All
。
room.Users.All(user => user.userId == request.FriendId || user.userId == request.RequestUserId)
然而All
也為空集返回 true(即當room.Users
為空時),所以它必須與另一個調用結合以消除這種情況
room.Users.Any() && room.Users.All(user =>
user.userId == request.FriendId || user.userId == request.RequestUserId)
這將產生所需的結果,但效率低下,因為涉及兩個子查詢而不是一個。
因此,最好的辦法是使用我所說的“條件計數”並將結果計數與兩 (2) 進行比較:
room.Users.Count(user =>
user.userId == request.FriendId || user.userId == request.RequestUserId) == 2
也可以用這樣的輸入更通用地表達(因為它支持超過 2 個)
// could contain more than two ids and doesn't need to be array
var userIds = new [] { request.FriendId, request.RequestUserId }.AsEnumerable();
和查詢條件如
room.Users.Count(user => userIds.Contains(user.userId)) == userIds.Count()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.